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

  1. Fix the formFieldValidationExpression so it returns a boolean: use ${myFlag == 'true'} style comparisons instead of raw values.
  2. Check the variable the expression reads is actually set (missing variables often evaluate to null).
  3. Test the expression with the expression manager / in a unit test against representative variables.
  4. 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

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


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