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).

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.

Appendix: 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)