flowable/flowable-engine · error · FlowableIllegalArgumentException
name expression does not resolve to a string:
Error message
name expression does not resolve to a string:
What it means
HumanTaskActivityBehavior resolves the task name from a name expression when configured. If the expression evaluates to a non-String, non-null object, the engine cannot safely assign it to the task name and throws FlowableIllegalArgumentException. Null values are tolerated (name stays unset), but wrong types are not.
Solutions
- Convert the value to a String inside the expression, e.g. ${someNumber.toString()} or ${'Task for ' + customerName}.
- Store a String-typed variable for the task name and reference that instead.
- If the value is a complex object, reference a specific string field, e.g. ${customer.name} instead of ${customer}.
- Update the case model/form so the variable is declared and set as a string.
Example fix
// before: numeric variable used directly -> Integer
<humanTask nameExpression="${orderNumber}"/>
// after
<humanTask nameExpression="${orderNumber.toString()}"/> // or store a String variable Defensive patterns
Strategy: type-guard
Validate before calling
Object nameVal = caseVariables.get("taskNameVar");
if (nameVal != null && !(nameVal instanceof String)) {
throw new IllegalArgumentException("taskNameVar must be a String, got: " + nameVal.getClass());
} Type guard
if (nameValue instanceof String s) {
taskEntity.setName(s); // safe assignment
} Try / catch
try {
caseRuntimeService.triggerPlanItemInstance(planItemId);
} catch (FlowableIllegalArgumentException e) {
if (e.getMessage().startsWith("name expression does not resolve to a string")) {
log.error("Task name expression returned non-string for case {}", caseInstanceId);
}
throw e;
} Prevention
- Declare task-name variables as strings in forms/data objects
- Use .toString() or string concatenation inside expressions for non-string values
- Reference specific string fields of complex objects, not the object itself
When it happens
Trigger: handleTaskName evaluates the name expression and the resulting value is neither null nor a String — e.g. an Integer, Boolean, Map, or JSON object.
Common situations: Case variable holding a number used directly as task name (e.g. ${caseCount}); data object fields returning parsed JSON objects; expressions returning collections; changes in variable type after a model update.
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
- documentation expression does not resolve to a string:
- Category 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/cb1722caef863516.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/behavior/impl/HumanTaskActivityBehavior.java:197
protected void handleTaskName(PlanItemInstanceEntity planItemInstanceEntity, ExpressionManager expressionManager,
TaskEntity taskEntity, CreateHumanTaskBeforeContext beforeContext, MigrationContext migrationContext) {
String nameStringValue = null;
if (migrationContext != null && migrationContext.getName() != null) {
nameStringValue = migrationContext.getName();
} else if (StringUtils.isNotEmpty(beforeContext.getName())) {
nameStringValue = beforeContext.getName();
}
if (StringUtils.isNotEmpty(nameStringValue)) {
Object name = expressionManager.createExpression(nameStringValue).getValue(planItemInstanceEntity);
if (name != null) {
if (name instanceof String) {
taskEntity.setName((String) name);
} else {
throw new FlowableIllegalArgumentException("name expression does not resolve to a string: " + beforeContext.getName());
}
}
}
}
protected void handleTaskDescription(PlanItemInstanceEntity planItemInstanceEntity, ExpressionManager expressionManager,
TaskEntity taskEntity, CreateHumanTaskBeforeContext beforeContext) {
if (StringUtils.isNotEmpty(beforeContext.getDescription())) {
Object description = expressionManager.createExpression(beforeContext.getDescription()).getValue(planItemInstanceEntity);
if (description != null) {
if (description instanceof String) {
taskEntity.setDescription((String) description);
} else {
throw new FlowableIllegalArgumentException("documentation expression does not resolve to a string: " + beforeContext.getDescription());
}
}
}View on GitHub (pinned to d6d39ce1c6)