apache/seatunnel · error · RuntimeException

Json parse list exception!

Error message

Json parse list exception!

What it means

Signals that Jackson failed to deserialize the input string into a List<T> inside JsonUtils.toList. The method accepts any json string plus a target element class, so the exception fires when the payload is not valid JSON or its top-level structure is not a JSON array (or elements do not match the expected type); the original Jackson exception is wrapped in a generic RuntimeException with only a sentinel message, so the true cause (e.g. mismatched JSON structure) is only visible in the wrapped cause.

Source

Thrown at seatunnel-common/src/main/java/org/apache/seatunnel/common/utils/JsonUtils.java:157

    /**
     * json to list
     *
     * @param json json string
     * @param clazz class
     * @param <T> T
     * @return list
     */
    public static <T> List<T> toList(String json, Class<T> clazz) {
        if (StringUtils.isEmpty(json)) {
            return Collections.emptyList();
        }

        try {
            CollectionType listType =
                    OBJECT_MAPPER.getTypeFactory().constructCollectionType(ArrayList.class, clazz);
            return OBJECT_MAPPER.readValue(json, listType);
        } catch (Exception e) {
            throw new RuntimeException("Json parse list exception!", e);
        }
    }

    /**
     * Method for finding a JSON Object field with specified name in this node or its child nodes,
     * and returning value it has. If no matching field is found in this node or its descendants,
     * returns null.
     *
     * @param jsonNode json node
     * @param fieldName Name of field to look for
     * @return Value of first matching node found, if any; null if none
     */
    public static String findValue(JsonNode jsonNode, String fieldName) {
        JsonNode node = jsonNode.findValue(fieldName);

        if (node == null) {
            return null;
        }

View on GitHub (pinned to cf67b549a7)

Solutions

  1. Inspect the cause: 'Cannot deserialize ... out of START_OBJECT' means the input is not an array
  2. Confirm the payload is a JSON array starting with '['; if a single object, wrap it or use parseObject
  3. Verify element class field types match the JSON
  4. Pre-validate with a quick readTree check that the node is an array

Example fix

// before
List<Item> items = JsonUtils.toList(singleObjectJson, Item.class); // not an array
// after
List<Item> items = JsonUtils.toList("[" + singleObjectJson + "]", Item.class);
Defensive patterns

Strategy: try-catch

Validate before calling

boolean isJsonArray(String s) { return s != null && s.trim().startsWith("["); }

Try / catch

try {
    List<Item> items = JsonUtils.toList(json, Item.class);
} catch (RuntimeException e) {
    log.error("list parse failed: {}", e.getCause());
    items = Collections.emptyList();
}

Prevention

When it happens

Trigger: Calling JsonUtils.toList(json, clazz) with input that is not a JSON array (a plain object, scalar, or invalid JSON), or elements that cannot be bound to the element class.

Common situations: A service returns a single object instead of a list after a version change, JSON contains objects where the element class expects other types, whitespace/malformed JSON from logs or files.

Understand the failure class

Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.

Related errors


AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10). Data as JSON: /api/errors/48452ec2ca40a3b7. Report an issue: GitHub.