flowable/flowable-engine · error · FlowableException
Unable to resolve formFieldValidationExpression to boolean v
Error message
Unable to resolve formFieldValidationExpression to boolean value for ${variableContainer} What it means
When evaluating a task's formFieldValidationExpression, Flowable coerces the expression result to Boolean via getBoolean. If the expression evaluates to something that is not a Boolean (so getBoolean returns null), this FlowableException is thrown because the validation flag must be a definitive boolean.
Source
Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/TaskHelper.java:697
}
}
public static boolean isFormFieldValidationEnabled(VariableContainer variableContainer,
ProcessEngineConfigurationImpl processEngineConfiguration, String formFieldValidationExpression) {
if (StringUtils.isNotEmpty(formFieldValidationExpression)) {
Boolean formFieldValidation = getBoolean(formFieldValidationExpression);
if (formFieldValidation != null) {
return formFieldValidation;
}
if (variableContainer != null) {
ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
Boolean formFieldValidationValue = getBoolean(
expressionManager.createExpression(formFieldValidationExpression).getValue(variableContainer)
);
if (formFieldValidationValue == null) {
throw new FlowableException("Unable to resolve formFieldValidationExpression to boolean value for " + variableContainer);
}
return formFieldValidationValue;
}
throw new FlowableException("Unable to resolve formFieldValidationExpression without variable container");
}
return true;
}
protected static void bulkDeleteHistoricTaskInstances(Collection<String> taskIds, ProcessEngineConfigurationImpl processEngineConfiguration) {
HistoricTaskService historicTaskService = processEngineConfiguration.getTaskServiceConfiguration().getHistoricTaskService();
List<String> subTaskIds = historicTaskService.findHistoricTaskIdsByParentTaskIds(taskIds);
if (subTaskIds != null && !subTaskIds.isEmpty()) {
bulkDeleteHistoricTaskInstances(subTaskIds, processEngineConfiguration);
}
processEngineConfiguration.getCommentEntityManager().bulkDeleteCommentsForTaskIds(taskIds);
processEngineConfiguration.getAttachmentEntityManager().bulkDeleteAttachmentsByTaskId(taskIds);
View on GitHub (pinned to d6d39ce1c6)
Solutions
- Fix the formFieldValidationExpression so it returns a boolean: use ${myFlag == 'true'} style comparisons instead of raw values.
- Check the variable the expression reads is actually set (missing variables often evaluate to null).
- Test the expression with the expression manager / in a unit test against representative variables.
- If a default should apply, wrap the expression so it never resolves to a non-boolean, e.g. ${flag != null && flag == true}.
Example fix
// before (bpmn xml)
<flowable:formFieldValidationExpression>${validationLevel}</flowable:formFieldValidationExpression>
// after
<flowable:formFieldValidationExpression>${validationLevel == 'strict'}</flowable:formFieldValidationExpression> Defensive patterns
Strategy: validation
Validate before calling
Object v = expressionManager.createExpression(expr).getValue(variableContainer);
if (!(v instanceof Boolean) && !("true".equals(v) || "false".equals(v))) throw new IllegalArgumentException("formFieldValidationExpression must resolve to boolean"); Type guard
boolean isBooleanValue(Object o) { return o instanceof Boolean || "true".equals(o) || "false".equals(o); } Try / catch
try { /* form handling */ } catch (FlowableException e) { if (e.getMessage().contains("formFieldValidationExpression")) log.error("Bad validation expr: {}", e.getMessage()); else throw e; } Prevention
- Write validation expressions as explicit comparisons (${x == 'true'})
- Unit-test form expressions with representative variable sets
- Avoid raw variable values in boolean contexts
When it happens
Trigger: A task/form definition carries a formFieldValidationExpression whose evaluation against the variableContainer yields a non-boolean (e.g. a String like "yes", a number, or null) while a variable container is present.
Common situations: Typo in the expression so it resolves to null; expression returning a string that is not 'true'/'false'; custom expression functions returning Object; form field configs copied from other engines with different truthiness rules.
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
- Unable to resolve formFieldValidationExpression to boolean v
- Unable to resolve formFieldValidationExpression without vari
- decisionTableReferenceKey expression does not resolve to a s
- Skip expression does not resolve to a boolean: " + skipExpre
- Unable to resolve formFieldValidationExpression without vari
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/95a12dbba85b9a95.
Report an issue: GitHub.