flowable/flowable-engine · error · FlowableException
Include in stage overview expression does not resolve to a…
Error message
Include in stage overview expression does not resolve to a boolean value ${includeInStageOverview}: ${stageValueObject} for ${variableContainer} What it means
GetStageOverviewCmd evaluates the stage's 'include in stage overview' expression and requires it to resolve to a java.lang.Boolean. Flowable throws FlowableException when the expression yields any other type (String, Integer, null), because the result is cast directly to Boolean.
Solutions
- Change the expression so it yields a boolean, e.g. ${includeFlag == 'true'} or ${booleanVar}
- Store the underlying case variable as a Boolean (caseService.setVariable(id, "includeFlag", true)) rather than a String
- Add a default: ${includeFlag != null && includeFlag == true} to guard against null
- Inspect the referenced variable in the running case instance to see its actual type
Example fix
// before (expression resolves to String)
<planItemDefinition ... flowable:includeInStageOverviewExpression="${includeFlag}"/>
// after
<planItemDefinition ... flowable:includeInStageOverviewExpression="${includeFlag == 'true'}"/> Defensive patterns
Strategy: validation
Validate before calling
Object v = caseService.getVariable(caseInstanceId, "includeFlag");
if (!(v instanceof Boolean)) {
throw new IllegalStateException("includeFlag must be a Boolean, got: " + (v == null ? "null" : v.getClass().getName()));
} Type guard
boolean isBooleanExpressionValue(Object o) { return o instanceof Boolean; } Try / catch
try {
List<StageResponse> stages = cmmnRuntimeService.getStageOverview(caseInstanceId, null);
} catch (FlowableException e) {
if (e.getMessage().startsWith("Include in stage overview expression")) {
// fix model expression / variable type
}
} Prevention
- Keep includeInStageOverview expressions boolean-typed (${flag}, ${a == b})
- Store flags as Boolean case variables, not Strings
- Add null-safe defaults in expressions: ${flag != null && flag == true}
When it happens
Trigger: A stage plan item's includeInStageOverviewExpression (stage overview expression) evaluates against case variables and returns a non-Boolean, e.g. the expression references a String variable like ${includeFlag} where includeFlag='true'.
Common situations: Setting the expression to a variable holding the string 'true' instead of a boolean; expression resolving to null because the variable is missing; using an expression that returns a number or object.
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
- Category expression does not resolve to a string:
- documentation expression does not resolve to a string:
- Due date expression does not resolve to a Date, Instant…
- FormKey expression does not resolve to a string:
- Include in stage overview expression does not resolve to a…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/13be870904035e27.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/GetStageOverviewCmd.java:151
// If not ended or current, it's implicitly a future one
if (planItemInstance.isPresent()) {
stageResponse.setEndTime(planItemInstance.get().getEndedTime());
stageResponse.setEnded(stageResponse.getEndTime() != null);
stageResponse.setCurrent(PlanItemInstanceState.ACTIVE.equals(planItemInstance.get().getState()));
}
stageResponses.add(stageResponse);
}
}
return stageResponses;
}
protected boolean evaluateIncludeInStageOverviewExpression(Expression stageExpression, String includeInStageOverview, VariableContainer variableContainer) {
Object stageValueObject = stageExpression.getValue(variableContainer);
if (!(stageValueObject instanceof Boolean)) {
throw new FlowableException("Include in stage overview expression does not resolve to a boolean value " +
includeInStageOverview + ": " + stageValueObject + " for " + variableContainer);
}
return (Boolean) stageValueObject;
}
protected Date getPlanItemInstanceEndTime(List<PlanItemInstance> planItemInstances, PlanItemDefinition planItemDefinition) {
return getPlanItemInstance(planItemInstances, planItemDefinition)
.map(PlanItemInstance::getEndedTime)
.orElse(null);
}
protected Optional<PlanItemInstance> getPlanItemInstance(List<PlanItemInstance> planItemInstances, PlanItemDefinition planItemDefinition) {
PlanItemInstance planItemInstance = null;
for (PlanItemInstance p : planItemInstances) {
if (p.getPlanItemDefinitionId().equals(planItemDefinition.getId())) {
if (p.getEndedTime() == null) {View on GitHub (pinned to d6d39ce1c6)