flowable/flowable-engine · error · FlowableException

JSON string does not represent an array:

Error message

JSON string does not represent an array: 

What it means

convertToArray handles IO parameters declared as type 'array'. For String inputs it parses the string with the VariableJsonMapper and requires the resulting node to be a JSON array. If the parsed node is an object or scalar, Flowable throws this FlowableException echoing the string content.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/DefaultVariableValueConversionHandler.java:191

            Object jsonNode = variableJsonMapper.readTree(stringValue);
            if (JsonUtil.isObjectNode(jsonNode)) {
                return jsonNode;
            }
            throw new FlowableException("JSON string does not represent an object: " + stringValue);
        }
        throw new FlowableException("Cannot convert value of type " + value.getClass().getName() + " to JSON object");
    }

    protected Object convertToArray(Object value, VariableJsonMapper variableJsonMapper) {
        if (value != null && JsonUtil.isArrayNode(value)) {
            return value;
        }
        if (value instanceof String stringValue) {
            Object jsonNode = variableJsonMapper.readTree(stringValue);
            if (JsonUtil.isArrayNode(jsonNode)) {
                return jsonNode;
            }
            throw new FlowableException("JSON string does not represent an array: " + stringValue);
        }
        throw new FlowableException("Cannot convert value of type " + value.getClass().getName() + " to JSON array");
    }

    /**
     * Parses an ISO 8601 duration/period string (e.g. "P10D", "PT10H", "P1Y2M3DT4H") and adds it to the current time.
     * Uses the same parsing logic as {@link org.flowable.common.engine.impl.calendar.DueDateBusinessCalendar}.
     */
    protected ZonedDateTime addDurationToNow(String durationString) {
        ZonedDateTime now = ZonedDateTime.now();
        Period period;
        Duration duration;
        if (durationString.startsWith("PT")) {
            period = Period.ZERO;
            duration = Duration.parse(durationString);
        } else {
            int timeIndex = durationString.indexOf('T');
            if (timeIndex > 0) {

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Wrap the payload in a JSON array: '{"a":1}' -> '[{"a":1}]'.
  2. If the value is an object, change the declared parameter type to 'json'.
  3. Pass a Jackson ArrayNode directly instead of a String.
  4. Pre-validate: JsonUtil.isArrayNode(mapper.readTree(s)) before binding.

Example fix

// before
execution.setVariable("items", "{\"id\":1}");
// after
execution.setVariable("items", "[{\"id\":1}]");
Defensive patterns

Strategy: validation

Validate before calling

if (value instanceof String s) {
    Object node = jsonMapper.readTree(s);
    if (!(node instanceof com.fasterxml.jackson.databind.JsonNode n) || !n.isArray()) {
        throw new IllegalArgumentException("'array' parameter string must parse to a JSON array");
    }
}

Type guard

static boolean isJsonArrayString(String s) {
    String t = s == null ? "" : s.trim();
    return t.startsWith("[") && t.endsWith("]");
}

Try / catch

try {
    Object arr = conversionHandler.convertValue(value, "array", mapper);
} catch (FlowableException e) {
    if (e.getMessage().startsWith("JSON string does not represent an array")) { /* wrap in [...] or switch to 'json' type */ }
    else throw e;
}

Prevention

When it happens

Trigger: Binding a JSON string like '{"a":1}' or '"text"' to an 'array' IO parameter; a single element that was serialized as a bare object instead of wrapped in [ ... ].

Common situations: APIs returning a single object where callers expected a list and passed the string through unchanged; swapping 'json' and 'array' declarations in the model; hand-written default values in BPMN XML missing the surrounding brackets.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/58bb09ab5a620ba3. Report an issue: GitHub.