apache/dolphinscheduler · error · RuntimeException

Json deserialization exception.

Error message

Json deserialization exception.

What it means

JSONUtils.parseArray(String) parses a JSON string into an ArrayNode by delegating to objectMapper.readTree and casting. Any parsing failure is wrapped in a RuntimeException with this message. It fails both when the text is invalid JSON and when the parsed tree is not an array (ClassCastException from the cast).

Source

Thrown at dolphinscheduler-common/src/main/java/org/apache/dolphinscheduler/common/utils/JSONUtils.java:353

    }

    public static ObjectNode parseObject(String text) {
        try {
            if (StringUtils.isEmpty(text)) {
                return parseObject(text, ObjectNode.class);
            } else {
                return (ObjectNode) objectMapper.readTree(text);
            }
        } catch (Exception e) {
            throw new RuntimeException("String json deserialization exception.", e);
        }
    }

    public static ArrayNode parseArray(String text) {
        try {
            return (ArrayNode) objectMapper.readTree(text);
        } catch (Exception e) {
            throw new RuntimeException("Json deserialization exception.", e);
        }
    }

    /**
     * json serializer
     */
    public static class JsonDataSerializer extends JsonSerializer<String> {

        @Override
        public void serialize(String value, JsonGenerator gen, SerializerProvider provider) throws IOException {
            gen.writeRawValue(value);
        }

    }

    public static class JsonDataDeserializer extends JsonDeserializer<String> {

        @Override

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Check the input string: it must start with '[' and be well-formed JSON
  2. Verify the upstream schema — if the value may be an object, parse with parseObject and read the array field from it
  3. Catch the RuntimeException and return Collections.emptyList() when the input is optional/blank
  4. Validate the payload shape with readTree + isArray before casting
  5. Fix the producer so it emits a JSON array

Example fix

// before
ArrayNode nodes = JSONUtils.parseArray(configJson);
// after
ArrayNode nodes = configJson != null && configJson.trim().startsWith("[")
    ? JSONUtils.parseArray(configJson)
    : JsonNodeFactory.instance.arrayNode();
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidJsonArray(String s) {
  if (s == null || !s.trim().startsWith("[")) return false;
  try { return JSONUtils.parseArray(s).isArray(); } catch (Exception e) { return false; }
}

Type guard

ArrayNode safeParseArray(String s) {
  if (s == null || !s.trim().startsWith("[")) return JsonNodeFactory.instance.arrayNode();
  try { return JSONUtils.parseArray(s); } catch (Exception e) { return JsonNodeFactory.instance.arrayNode(); }
}

Try / catch

try {
  ArrayNode arr = JSONUtils.parseArray(text);
} catch (RuntimeException e) {
  log.warn("Expected a JSON array but got: {}", text, e);
  arr = JsonNodeFactory.instance.arrayNode();
}

Prevention

When it happens

Trigger: Calling JSONUtils.parseArray(text) where text is malformed JSON, or where text is valid JSON but not an array (e.g. an object '{...}', a bare string, or a number), causing readTree to succeed but the (ArrayNode) cast to fail.

Common situations: An API or config value that changed shape across versions from array to object; passing a JSON object where a list was expected; empty or whitespace-only string produced by a failed upstream call.

Understand the failure class

Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.

Related errors


AI-assisted analysis of apache/dolphinscheduler@02eac45a1b (2026-09-06). Data as JSON: /api/errors/fd7c8a86ef42a52c. Report an issue: GitHub.