apache/dolphinscheduler · error · RuntimeException

String json deserialization exception.

Error message

String json deserialization exception.

What it means

JSONUtils.parseObject(String) parses a JSON string into an ObjectNode. If the text is non-empty but not valid JSON (or readTree otherwise fails), it wraps the exception in a RuntimeException with this generic message. Empty strings are delegated to parseObject(text, ObjectNode.class) and do not reach this throw site.

Source

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

            return null;
        }
        try {
            return toJsonString(obj).getBytes(UTF_8);
        } catch (Exception e) {
            throw new IllegalArgumentException("Object: " + obj + " to json serialization exception.", e);
        }

    }

    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 {

View on GitHub (pinned to 02eac45a1b)

Solutions

  1. Log/print the input string and validate it with a JSON linter to find the syntax error
  2. If the source is an HTTP endpoint, check the response content-type and body before parsing (it may be an HTML error page)
  3. Ensure the string is not truncated or double-escaped (e.g. \" inside JSON stored in another JSON)
  4. Use the tryParseObject/safe variant or catch the RuntimeException and fall back to a default ObjectNode
  5. Fix the producer of the JSON to emit valid UTF-8 JSON

Example fix

// before
ObjectNode node = JSONUtils.parseObject(responseBody);
// after
ObjectNode node = StringUtils.isNotBlank(responseBody) && responseBody.trim().startsWith("{")
    ? JSONUtils.parseObject(responseBody)
    : JsonNodeFactory.instance.objectNode();
Defensive patterns

Strategy: try-catch

Validate before calling

boolean isValidJsonObject(String s) {
  if (s == null || s.trim().isEmpty()) return false;
  try { return JSONUtils.parseObject(s).isObject(); } catch (Exception e) { return false; }
}

Type guard

ObjectNode safeParseObject(String s) {
  try { return JSONUtils.parseObject(s); } catch (Exception e) { return JsonNodeFactory.instance.objectNode(); }
}

Try / catch

try {
  ObjectNode node = JSONUtils.parseObject(text);
} catch (RuntimeException e) {
  log.warn("Invalid JSON input: {}", text, e);
  node = JsonNodeFactory.instance.objectNode(); // or rethrow with context
}

Prevention

When it happens

Trigger: Calling JSONUtils.parseObject(text) with malformed JSON, truncated JSON, or a JSON value that readTree cannot parse (e.g. invalid escape sequences, trailing garbage).

Common situations: Reading a JSON config file or task parameter that was hand-edited; decoding a response body from an external service that returned HTML or an error page instead of JSON; string truncated by a length limit or encoding mismatch.

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/3d6d1de0eaaf96b8. Report an issue: GitHub.