flowable/flowable-engine · warning

Out parameter target expression

Error message

Out parameter target expression {} did not resolve to a variable name, this is most likely a programmatic error

What it means

Warning logged by ChildBpmnCaseInstanceStateChangeCallback.stateChanged when a case-to-process callback's out-parameter targetExpression evaluates to null. The expression should produce the target variable name for propagating case state into the BPMN process; null means the model is misconfigured, so the variable name falls back and the copy may be skipped.

Solutions

  1. Fix the outParameter targetExpression in the process/case model so it evaluates to a non-null variable name.
  2. Initialize the referenced case variable before the callback executes.
  3. Replace targetExpression with the plain target attribute for fixed variable names.
  4. Check expression manager configuration (custom beans referenced in the expression) resolves correctly.

Example fix

// before
<flowable:outParameter source="caseOutcome" targetExpression="${outcomeName}" /> <!-- null -->
// after
<flowable:outParameter source="caseOutcome" target="caseOutcome" />
Defensive patterns

Strategy: validation

Validate before calling

Object resolved = cmmnEngineConfiguration.getExpressionManager()
    .createExpression(outParameter.getTargetExpression()).getValue(caseInstance);
if (resolved == null) throw new IllegalStateException("targetExpression resolves to null: " + outParameter.getTargetExpression());

Try / catch

null

Prevention

When it happens

Trigger: A BPMN process with flowable:caseTask/in-flow callbacks declares an outParameter with targetExpression; when stateChanged fires, the expression evaluated against the case instance returns null.

Common situations: Expression referencing a case variable that was never initialized; wrong expression language or typo returning null; using targetExpression where a static target would suffice.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/callback/ChildBpmnCaseInstanceStateChangeCallback.java:80

                Object value = null;
                if (StringUtils.isNotEmpty(outParameter.getSourceExpression())) {
                    Expression expression = cmmnEngineConfiguration.getExpressionManager().createExpression(outParameter.getSourceExpression().trim());
                    value = expression.getValue(caseInstance);

                } else {
                    value = caseInstance.getVariable(outParameter.getSource());
                }

                String variableName = null;
                if (StringUtils.isNotEmpty(outParameter.getTarget())) {
                    variableName = outParameter.getTarget();

                } else if (StringUtils.isNotEmpty(outParameter.getTargetExpression())) {
                    Object variableNameValue = cmmnEngineConfiguration.getExpressionManager().createExpression(outParameter.getTargetExpression()).getValue(caseInstance);
                    if (variableNameValue != null) {
                        variableName = variableNameValue.toString();
                    } else {
                        LOGGER.warn("Out parameter target expression {} did not resolve to a variable name, this is most likely a programmatic error",
                            outParameter.getTargetExpression());
                    }

                }

                String conversionType = null;
                if (StringUtils.isNotEmpty(outParameter.getTargetType())) {
                    conversionType = outParameter.getTargetType();
                } else if (StringUtils.isNotEmpty(outParameter.getSourceType())) {
                    conversionType = outParameter.getSourceType();
                }

                if (conversionType != null && value != null) {
                    value = cmmnEngineConfiguration.getVariableValueConversionHandler()
                            .convertValue(value, conversionType, cmmnEngineConfiguration.getVariableJsonMapper());
                }

                variables.put(variableName, value);

View on GitHub (pinned to d6d39ce1c6)