{"record":{"id":"9600de0046230200","repo":"flowable/flowable-engine","slug":"forminfo-is-null","errorCode":null,"errorMessage":"formInfo is null","messagePattern":"formInfo is null","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceTransitionBuilderImpl.java","lineNumber":78,"sourceCode":"        variables.put(variableName, variableValue);\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceTransitionBuilder variables(Map<String, Object> variables) {\n        if (this.variables == null) {\n            this.variables = new HashMap<>();\n        }\n        if (variables != null) {\n            this.variables.putAll(variables);\n        }\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceTransitionBuilder formVariables(Map<String, Object> variables, FormInfo formInfo, String outcome) {\n        if (formInfo == null) {\n            throw new FlowableIllegalArgumentException(\"formInfo is null\");\n        }\n\n        if (this.formVariables == null) {\n            this.formVariables = new HashMap<>();\n        }\n\n        if (variables != null) {\n            this.formVariables.putAll(variables);\n        }\n\n        this.formOutcome = outcome;\n        this.formInfo = formInfo;\n        return this;\n    }\n\n    @Override\n    public PlanItemInstanceTransitionBuilder localVariable(String variableName, Object variableValue) {\n        if (localVariables == null) {","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/runtime/PlanItemInstanceTransitionBuilderImpl.java#L60-L96","documentation":"PlanItemInstanceTransitionBuilderImpl.formVariables(Map, FormInfo, String) throws FlowableIllegalArgumentException when the formInfo argument is null. Form metadata is required to bind the submitted variables and outcome to a form definition, so the API refuses null.","triggerScenarios":"Calling transitionBuilder.formVariables(variables, null, outcome), typically when form metadata retrieval (FormRepositoryService/FormService) returned null or was skipped.","commonSituations":"Start-form handling in custom REST endpoints where formInfo lookup failed silently; migration from older Flowable versions where forms were optional; conditional form deployment missing in the target environment.","solutions":["Fetch a valid FormInfo via FormService.getFormModelWithAllVariables() (or FormRepositoryService) before calling formVariables.","If there is no form, call formVariables(variables, null, null) is invalid — instead use the plain variables API (variables(map)) on the transition builder.","Check that the form definition is deployed and the lookup key is correct so formInfo is not null."],"exampleFix":"// before\nbuilder.formVariables(vars, null, outcome); // formInfo null\n// after\nFormInfo formInfo = formService.createFormInfo().formKey(\"startForm\").tenantId(tenant).getFormInfo();\nbuilder.formVariables(vars, formInfo, outcome);","handlingStrategy":"validation","validationCode":"if (formInfo == null) { usePlainVariablesInstead = true; }","typeGuard":null,"tryCatchPattern":"try { builder.formVariables(vars, formInfo, outcome); } catch (FlowableIllegalArgumentException e) { builder.variables(vars); }","preventionTips":["Resolve FormInfo from FormService before touching the transition builder.","Fall back to variables(map) when no form is deployed."],"tags":["flowable","cmmn","form","null-argument"],"backgroundTag":"null-argument","analyzedSha":"d6d39ce1c69ff244f2d9dc6af756a9b95e865586","analyzedAt":"2026-09-11T06:41:19.413Z","contentChangedAt":"2026-09-11T06:41:19.413Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}