flowable/flowable-engine · error · FlowableException

Unsupported value type ${value == null ? "null" : value.getC

Error message

Unsupported value type ${value == null ? "null" : value.getClass().getName()}

What it means

FlowableJackson2JsonNode.asJsonNode only accepts values that are already Jackson 2 JsonNode instances or values recognized by JsonUtil.isJsonNode (Jackson 3 nodes). Anything else — including null and arbitrary objects like String or Map — is rejected with a FlowableException naming the actual runtime type.

Source

Thrown at modules/flowable-engine-common/src/main/java/org/flowable/common/engine/impl/json/jackson2/FlowableJackson2JsonNode.java:211

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

    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 3 node
            try {
                return objectMapperSupplier.get().readTree(value.toString());
            } catch (JsonProcessingException e) {
                throw new FlowableException("Failed to parse jase", e);
            }
        } 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 FlowableJackson2ArrayNode(arrayNode);
        } else if (jsonNode instanceof ObjectNode objectNode) {
            return new FlowableJackson2ObjectNode(objectNode);
        } else if (jsonNode != null) {
            return new FlowableJackson2JsonNode<>(jsonNode);
        }
        return null;
    }
}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Parse the value first (JsonUtil/jsonMapper.readTree) before passing it to asJsonNode
  2. Check for null and validate the value is a JsonNode (or isJsonNode) before calling
  3. Ensure the variable was created as a JSON-typed variable, not a plain string

Example fix

// before
JsonNode node = FlowableJackson2JsonNode.asJsonNode(variableValue);
// after
JsonNode node = variableValue instanceof JsonNode
    ? (JsonNode) variableValue
    : FlowableJackson2JsonNode.asJsonNode(
        JsonUtil.readTree(variableValue == null ? "null" : variableValue.toString()));
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 type: " + value.getClass());

Type guard

boolean isJsonNodeValue(Object v) { return v instanceof com.fasterxml.jackson.databind.JsonNode || JsonUtil.isJsonNode(v); }

Try / catch

try { return FlowableJackson2JsonNode.asJsonNode(v); } catch (FlowableException e) { return FlowableJackson2JsonNode.asJsonNode(JsonUtil.readTree(String.valueOf(v))); }

Prevention

When it happens

Trigger: Calling FlowableJackson2JsonNode.asJsonNode(Object) with null, a plain String, Map, or any non-Jackson-node object; passing a variable fetched from storage that was not stored as a JSON node type.

Common situations: Reading process/execution variables expecting JSON but the variable was stored as a string; passing user-supplied objects into JSON conversion helpers; refactoring changed variable types between JSON string and JsonNode.

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