flowable/flowable-engine · error · FlowableException

could not create result variable: unrecognized mapping type

Error message

could not create result variable: unrecognized mapping type

What it means

Thrown by ExecutionVariableFactory.getExecutionVariable when the declared mapping type is not one of the four supported values (boolean, string, number, date). The factory has no conversion rule for the given type string, so it aborts; note the inner throw is then caught and rethrown as 'Could not create execution variable' with the cause chained by the surrounding catch block.

Solutions

  1. Set the output clause type to one of the supported values: boolean, string, number, or date.
  2. Normalize/validate the type string before calling (lowercase, map synonyms like 'long'/'integer'/'double' to 'number').
  3. If a richer type is required, convert the expression result yourself instead of routing through ExecutionVariableFactory.
  4. Catch FlowableException and log the offending type value so the model author can correct the DMN output definition.

Example fix

// before
String type = outputClause.getTypeRef(); // e.g. "long"
Object v = ExecutionVariableFactory.getExecutionVariable(type, result);
// after
String type = "long".equals(outputClause.getTypeRef()) ? "number" : outputClause.getTypeRef();
if (!List.of("boolean", "string", "number", "date").contains(type)) {
    throw new IllegalArgumentException("unsupported output type: " + type);
}
Object v = ExecutionVariableFactory.getExecutionVariable(type, result);
Defensive patterns

Strategy: validation

Validate before calling

if (!List.of("boolean","string","number","date").contains(type)) {
    throw new IllegalArgumentException("unsupported output type: " + type);
}
Object v = ExecutionVariableFactory.getExecutionVariable(type, result);

Type guard

boolean supportedType(String t) {
    return "boolean".equals(t) || "string".equals(t) || "number".equals(t) || "date".equals(t);
}

Try / catch

try {
    Object v = ExecutionVariableFactory.getExecutionVariable(type, result);
} catch (FlowableException e) {
    LOGGER.error("Unrecognized DMN output mapping type '{}' or conversion failed", type, e);
    // normalize type or reject the model with a clear message
}

Prevention

When it happens

Trigger: Calling getExecutionVariable with a type string outside {boolean,string,number,date} — e.g. a DMN output clause whose type is 'long', 'integer', 'json', a custom type name, or a capitalized/mispelled type like 'Boolean' or 'numerical'.

Common situations: DMN models authored with richer output types than the engine's mapping supports; type names produced by converters that don't normalize to the four supported strings; custom integrations passing an output type straight from a config file or UI dropdown.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-dmn-engine/src/main/java/org/flowable/dmn/engine/impl/el/ExecutionVariableFactory.java:84

                    executionVariable = ((BigInteger) expressionResult).longValue();
                } else {
                    executionVariable = Double.valueOf(expressionResult.toString());
                }
            } else if (StringUtils.equals("date", type)) {
                if (expressionResult instanceof Date) {
                    executionVariable = expressionResult;
                } else if (expressionResult instanceof Instant instant) {
                    executionVariable = Date.from(instant);
                } else if (expressionResult instanceof LocalDate localDate) {
                    executionVariable = Date.from(localDate.atStartOfDay().atZone(ZoneOffset.UTC).toInstant());
                } else if (expressionResult instanceof LocalDateTime localDateTime) {
                    executionVariable = Date.from(localDateTime.atZone(ZoneOffset.UTC).toInstant());
                } else {
                    executionVariable = DateUtil.parseDate(expressionResult.toString());
                }
            } else {
                LOGGER.error("could not create result variable: unrecognized mapping type");
                throw new FlowableException("could not create result variable: unrecognized mapping type");
            }
        } catch (Exception e) {
            LOGGER.error("could not create result variable", e);
            throw new FlowableException("Could not create execution variable", e);
        }

        return executionVariable;
    }

    public static List<Object> getExecutionVariables(String type, List<Object> expressionResults) {
        if (type == null || expressionResults == null) {
            return null;
        }

        List<Object> executionVariables = new ArrayList<>();
        for (Object expressionResult : expressionResults) {
            executionVariables.add(getExecutionVariable(type, expressionResult));
        }

View on GitHub (pinned to d6d39ce1c6)