{"record":{"id":"49337694fcda2f9d","repo":"flowable/flowable-engine","slug":"unable-to-resolve-formfieldvalidationexpression-wi","errorCode":null,"errorMessage":"Unable to resolve formFieldValidationExpression without variable container","messagePattern":"Unable to resolve formFieldValidationExpression without variable container","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/task/TaskHelper.java","lineNumber":275,"sourceCode":"    public static boolean isFormFieldValidationEnabled(VariableContainer variableContainer,\n        CmmnEngineConfiguration cmmnEngineConfiguration, String formFieldValidationExpression) {\n        if (StringUtils.isNotEmpty(formFieldValidationExpression)) {\n            Boolean formFieldValidation = getBoolean(formFieldValidationExpression);\n            if (formFieldValidation != null) {\n                return formFieldValidation;\n            }\n\n            if (variableContainer != null) {\n                ExpressionManager expressionManager = cmmnEngineConfiguration.getExpressionManager();\n                Boolean formFieldValidationValue = getBoolean(\n                    expressionManager.createExpression(formFieldValidationExpression).getValue(variableContainer)\n                );\n                if (formFieldValidationValue == null) {\n                    throw new FlowableException(\"Unable to resolve formFieldValidationExpression to boolean value for \" + variableContainer);\n                }\n                return formFieldValidationValue;\n            }\n            throw new FlowableException(\"Unable to resolve formFieldValidationExpression without variable container\");\n        }\n        return true;\n    }\n    \n    protected static void bulkDeleteHistoricTaskInstances(Collection<String> taskIds, CmmnEngineConfiguration cmmnEngineConfiguration) {\n        HistoricTaskService historicTaskService = cmmnEngineConfiguration.getTaskServiceConfiguration().getHistoricTaskService();\n        \n        List<String> subTaskIds = historicTaskService.findHistoricTaskIdsByParentTaskIds(taskIds);\n        if (subTaskIds != null && !subTaskIds.isEmpty()) {\n            bulkDeleteHistoricTaskInstances(subTaskIds, cmmnEngineConfiguration);\n        }\n        \n        cmmnEngineConfiguration.getVariableServiceConfiguration().getHistoricVariableService().bulkDeleteHistoricVariableInstancesByTaskIds(taskIds);\n        cmmnEngineConfiguration.getIdentityLinkServiceConfiguration().getHistoricIdentityLinkService().bulkDeleteHistoricIdentityLinksForTaskIds(taskIds);\n        \n        if (cmmnEngineConfiguration.isEnableEntityLinks()) {\n            cmmnEngineConfiguration.getEntityLinkServiceConfiguration().getHistoricEntityLinkService()\n                    .bulkDeleteHistoricEntityLinksForScopeTypeAndScopeIdsOrReferenceScopeIds(ScopeTypes.TASK, taskIds);","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/task/TaskHelper.java#L257-L293","documentation":"TaskHelper.isFormFieldValidationEnabled requires a VariableContainer when a formFieldValidationExpression is present; without one the expression cannot be evaluated at all, so the helper throws this FlowableException. It indicates the caller asked to evaluate form validation config but supplied no context variables.","triggerScenarios":"Calling isFormFieldValidationEnabled(cmmnEngineConfiguration, formFieldValidationExpression, null) — i.e. a non-null validation expression with a null variableContainer — typically when processing task form info outside a proper case/plan-item context.","commonSituations":"Custom form rendering code that resolves form info without loading the task's variables; historic/async paths where the variable container was dropped; calling the helper from a listener with an uninitialized container.","solutions":["Pass the task's/case's VariableContainer (e.g. the DelegateTask, PlanItemInstanceEntity, or a VariableScopeAdapter) instead of null","If no variables are available, don't set a formFieldValidationExpression (it defaults to validation enabled when expression is absent)","Ensure form-info processing happens in a context where CommandContextUtil can supply the proper variable container","Null-check and log before calling, failing fast with a clearer app-level error"],"exampleFix":"// before\nboolean enabled = TaskHelper.isFormFieldValidationEnabled(config, formInfo.getValidationExpression(), null);\n// after\nVariableContainer container = new VariableScopeAdapter(planItemInstanceEntity);\nboolean enabled = TaskHelper.isFormFieldValidationEnabled(config, formInfo.getValidationExpression(), container);","handlingStrategy":"validation","validationCode":"if (validationExpression != null && variableContainer == null) {\n    throw new IllegalArgumentException(\"formFieldValidationExpression set but no VariableContainer provided\");\n}","typeGuard":"null","tryCatchPattern":"try { return TaskHelper.isFormFieldValidationEnabled(cfg, expr, container); } catch (FlowableException e) { if (e.getMessage().equals(\"Unable to resolve formFieldValidationExpression without variable container\")) { log.warn(\"Missing variable container for form validation\"); return true; } throw e; }","preventionTips":["Always pass the task/plan-item VariableContainer when evaluating form info","Avoid setting formFieldValidationExpression in contexts without variable access","Null-check the container before calling the helper"],"tags":["cmmn","expression","form-validation","flowable"],"backgroundTag":"missing-required-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}