flowable/flowable-engine · error · FlowableException

Unsupported value type " + (value == null ? "null" : value.g

Error message

Unsupported value type " + (value == null ? "null" : value.getClass().getName())

What it means

FlowableJackson3JsonNode.asJsonNode (Jackson 3 variant) accepts Jackson JsonNode values and Jackson 2 nodes (detected via JsonUtil.isJsonNode, converted by re-parsing toString()), and throws FlowableException for anything else, including null and plain Java types. Note the message string in the throwing code concatenates without interpolation of the class name prefix; the actual message is 'Unsupported value type ' plus the type name.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/json/jackson3/FlowableJackson3JsonNode.java:226

    public String getNodeType() {
        return jsonNode.getNodeType().name();
    }

    protected static JsonNode asJsonNode(FlowableJsonNode value) {
        if (value == null) {
            return NullNode.getInstance();
        }
        return asJsonNode(value.getImplementationValue(), JsonMapper::shared);
    }

    protected static JsonNode asJsonNode(Object value, Supplier<ObjectMapper> objectMapperSupplier) {
        if (value instanceof JsonNode) {
            return (JsonNode) value;
        } else if (JsonUtil.isJsonNode(value)) {
            // This means it is a Jackson 2 node
            return objectMapperSupplier.get().readTree(value.toString());
        } else {
            throw new FlowableException("Unsupported value type " + (value == null ? "null" : value.getClass().getName()));
        }
    }

    public static FlowableJsonNode wrap(JsonNode jsonNode) {
        if (jsonNode instanceof ArrayNode arrayNode) {
            return new FlowableJackson3ArrayNode(arrayNode);
        } else if (jsonNode instanceof ObjectNode objectNode) {
            return new FlowableJackson3ObjectNode(objectNode);
        } else if (jsonNode != null) {
            return new FlowableJackson3JsonNode<>(jsonNode);
        }
        return null;
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Parse the value into a JsonNode before calling asJsonNode
  2. Null-check and instanceof-check the value before conversion
  3. Store variables with JSON node types so they round-trip as nodes

Example fix

// before
JsonNode node = FlowableJackson3JsonNode.asJsonNode(varValue);
// after
JsonNode node = (varValue instanceof JsonNode jn)
    ? jn
    : FlowableJackson3JsonNode.asJsonNode(jsonMapper.readTree(String.valueOf(varValue)));
Defensive patterns

Strategy: type-guard

Validate before calling

if (value == null) throw new IllegalArgumentException("Expected JSON node, got null");
if (!(value instanceof JsonNode) && !JsonUtil.isJsonNode(value)) throw new IllegalArgumentException("Unsupported: " + value.getClass());

Type guard

boolean isJackson3NodeValue(Object v) { return v instanceof tools.jackson.databind.JsonNode || JsonUtil.isJsonNode(v); }

Try / catch

try { return FlowableJackson3JsonNode.asJsonNode(v); } catch (FlowableException e) { logger.warn("Unsupported value type: {}", v == null ? "null" : v.getClass()); throw e; }

Prevention

When it happens

Trigger: Calling FlowableJackson3JsonNode.asJsonNode(Object) with null, a String, Map, or other non-Jackson-node object; passing a value stored as a JSON string variable into an API expecting a JsonNode.

Common situations: Mixing Jackson 2 and Jackson 3 in one application during migration; variables persisted as strings read through node-based APIs; helper methods given user objects instead of parsed nodes.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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