JSON troubleshooting

Jackson: Cannot deserialize value of type from Array or Object value

Fix Jackson MismatchedInputException when JSON arrays, objects and strings do not match your Java types, including the older START_ARRAY and START_OBJECT messages.

What the error means

The JSON is valid, but its shape does not match the Java type Jackson was asked to build. from Object value means Jackson found a JSON object where the type expects something else, such as a list. from Array value means it found an array where it expected an object or a single value. The message names the target type and the JSON token. Versions before 2.12 said out of START_OBJECT token or out of START_ARRAY token for the same mismatch.

Exact messages by runtime

Messages depend on the input and runtime version. Node and Python rows were reproduced locally. Other rows cite official documentation or source. Rows marked as fragments or templates preserve the source wording and are not complete exception transcripts. Browsers and libraries may append location details.

RuntimeMessageInput and evidence
Java / Jackson 2.12+ and 3.x, list targetMismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<com.example.Item>` from Object value (token `JsonToken.START_OBJECT`)readValue("{\"items\":[]}", new TypeReference<List<Item>>() {})
Source-derived from the Jackson 2.22 template; the type text depends on your class
Java / Jackson 2.12+ and 3.x, object targetCannot deserialize value of type `com.example.Item` from Array value (token `JsonToken.START_ARRAY`)readValue("[{\"id\":1}]", Item.class)
Source-derived from the same template
Java / Jackson 2.12+ and 3.x, String fieldCannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`){"address":{"city":"Pune"}} into a String address field
Source-derived; the reference chain suffix is omitted
Java / Jackson 2.10 and 2.11Cannot deserialize instance of `java.util.ArrayList<com.example.Item>` out of START_OBJECT tokenThe list example
Source-derived from the Jackson 2.11.4 template
Java / Jackson 2.9Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT tokenThe list example
Source-derived from the Jackson 2.9.10.8 template
Java / Jackson 2.8 and earlierCan not deserialize instance of java.util.ArrayList out of START_OBJECT tokenThe list example
Source-derived from the Jackson 2.8.11 template
C# / Json.NETCannot deserialize the current JSON object (e.g. {"name":"value"}) into type '{0}' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly.An object where a List<T> is expected
Json.NET 13.0.4 source template; first sentence shown
Go / encoding/jsonjson: cannot unmarshal object into Go value of type []main.ItemThe list example in Go
Source-derived from Go 1.27 decode.go

Causes you can reproduce

The response wraps the list in an object

Many APIs return {"items": [...]} or {"data": [...]}. Reading that object as a List fails with from Object value.

JAVA
record Item(long id) {}

String json = "{\"items\":[{\"id\":1}]}";
List<Item> items = new ObjectMapper().readValue(json, new TypeReference<List<Item>>() {});
// MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<...Item>` from Object value

One value arrives where a list is expected

Some APIs send a single object or string when there is one result and an array when there are several. A List field then sees an object or a string.

JAVA
record Order(List<String> tags) {}

new ObjectMapper().readValue("{\"tags\":\"new\"}", Order.class);
// MismatchedInputException: Cannot deserialize value of type `java.util.ArrayList<java.lang.String>` from String value

A field type differs from the JSON value

A String field cannot hold a nested object, and a single object field cannot hold an array.

JAVA
record User(String address) {}

new ObjectMapper().readValue("{\"address\":{\"city\":\"Pune\"}}", User.class);
// Cannot deserialize value of type `java.lang.String` from Object value (token `JsonToken.START_OBJECT`)

How to fix it

  1. Read the target type and the JSON token. The (through reference chain: ...) suffix names the class and property where it failed.
  2. Look at the JSON at that property. An object starts with {, an array with [.
  3. Change the Java type to match: a wrapper record for {"items": [...]}, a List or array for [...], and a nested record for {...}.
  4. If the API really sends either one value or a list, enable ACCEPT_SINGLE_VALUE_AS_ARRAY and document that contract.

Model the wrapper object

Records need Jackson 2.12 or later. The fragments run in a method that declares throws Exception.

JAVA
record Item(long id) {}
record ItemsResponse(List<Item> items) {}

ItemsResponse response = new ObjectMapper()
    .readValue("{\"items\":[{\"id\":1}]}", ItemsResponse.class);
List<Item> items = response.items();

Read a top-level array as a list

TypeReference keeps the element type, so each element becomes an Item instead of a Map.

JAVA
List<Item> items = new ObjectMapper()
    .readValue("[{\"id\":1}]", new TypeReference<List<Item>>() {});

Accept one value as a one-element list

Enable this only when the API documents both forms.

JAVA
ObjectMapper mapper = JsonMapper.builder()
    .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY)
    .build();
Order order = mapper.readValue("{\"tags\":\"new\"}", Order.class); // tags = [new]

Compare the JSON shape with your types

  1. Copy the exact JSON your code received, for example from a log or a failing test.
  2. Paste it into the Tool Kumar JSON viewer. The document stays in your browser.
  3. Open the tree at the property named in the error and check whether the value there is an object, an array or a single value. The JSON path finder copies the path to any value.
  4. Generate types from the same document with a converter listed under related tools, then compare them with your own classes or structs.

Frequently asked questions

What do START_OBJECT and START_ARRAY mean?

They are Jackson token names for { and [. Newer messages say Object value and Array value instead, and add the token name in parentheses.

Why does the message say ArrayList when my code asks for List?

Jackson builds an ArrayList for an abstract List type, so the message names the concrete type it tried to create.

Is this a JSON syntax error?

No. The document parsed successfully. The error is a mismatch between the JSON structure and your Java types, so fix the types or the producer, not the syntax.

Should I enable ACCEPT_SINGLE_VALUE_AS_ARRAY globally?

Only if every list in your input may arrive as a single value. Otherwise it hides real contract changes. You can enable it per property with @JsonFormat(with = JsonFormat.Feature.ACCEPT_SINGLE_VALUE_AS_ARRAY).

Standards and diagnostic sources

RFC 8259 and ECMA-404 define JSON syntax. Diagnostic wording belongs to the parser. The table links each cited message to its source.