{"record":{"id":"f4e42ec9daabfd6b","repo":"flowable/flowable-engine","slug":"variable-name-is-required-f4e42e","errorCode":null,"errorMessage":"Variable name is required.","messagePattern":"Variable name is required\\.","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-external-job-rest/src/main/java/org/flowable/external/job/rest/service/api/acquire/ExternalWorkerAcquireJobResource.java","lineNumber":278,"sourceCode":"            failureBuilder.retryTimeout(request.getRetryTimeout());\n        }\n\n        if (restApiInterceptor != null) {\n            restApiInterceptor.failExternalWorkerJob(job, request);\n        }\n\n        failureBuilder.fail();\n\n        return ResponseEntity.noContent().build();\n    }\n\n    protected Map<String, Object> extractVariables(List<EngineRestVariable> restVariables) {\n        if (restVariables != null && !restVariables.isEmpty()) {\n            Map<String, Object> variables = new HashMap<>();\n\n            for (EngineRestVariable restVariable : restVariables) {\n                if (restVariable.getName() == null) {\n                    throw new FlowableIllegalArgumentException(\"Variable name is required.\");\n                }\n\n                variables.put(restVariable.getName(), restResponseFactory.getVariableValue(restVariable));\n            }\n\n            return variables;\n        }\n\n        return Collections.emptyMap();\n    }\n\n    protected ExternalWorkerJobAcquireBuilder createExternalWorkerAcquireBuilder() {\n        if (managementService != null) {\n            return managementService.createExternalWorkerJobAcquireBuilder();\n        } else if (cmmnManagementService != null) {\n            return cmmnManagementService.createExternalWorkerJobAcquireBuilder();\n        } else {\n            throw new FlowableException(\"Cannot acquire external jobs. There is no BPMN or CMMN engine available\");","sourceCodeStart":260,"sourceCodeEnd":296,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-external-job-rest/src/main/java/org/flowable/external/job/rest/service/api/acquire/ExternalWorkerAcquireJobResource.java#L260-L296","documentation":"FlowableIllegalArgumentException thrown by extractVariables in ExternalWorkerAcquireJobResource when completing, erroring (BPMN) or terminating (CMMN) an external worker job with a variable entry whose name is null. Variable payloads must carry a name to be persisted in the engine. The library fails fast instead of storing an unnamed variable.","triggerScenarios":"POST to the external worker completion/BPMN-error/CMMN-terminate endpoints (or calls to completeJob/bpmnErrorJob/terminateCmmnJob) with a request body whose 'variables' array contains an item without a 'name' field, or with name explicitly null.","commonSituations":"Hand-written JSON payloads where a variable object only has {\"type\":\"string\",\"value\":\"x\"}; dynamic client code that builds variables from maps with null keys; deserialization dropping the name field due to mismatched DTO property naming.","solutions":["Add a non-null 'name' to every object in the request's variables array.","Validate the variables payload client-side before sending and reject entries with blank names.","Check the serialization code that produces EngineRestVariable instances to ensure the name property is populated."],"exampleFix":"// before\n{\"variables\":[{\"type\":\"string\",\"value\":\"approved\"}]}\n// after\n{\"variables\":[{\"name\":\"approved\",\"type\":\"string\",\"value\":\"approved\"}]}","handlingStrategy":"validation","validationCode":"if (body.getVariables() == null || body.getVariables().stream().anyMatch(v -> v.getName() == null || v.getName().isBlank())) {\n    throw new IllegalArgumentException(\"every variable needs a name\");\n}","typeGuard":"boolean hasName(EngineRestVariable v) { return v != null && v.getName() != null && !v.getName().isEmpty(); }","tryCatchPattern":"try { completeJob(jobId, workerId, vars, transientVars); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().contains(\"Variable name\")) { fixAndResendPayload(); } else { throw e; } }","preventionTips":["Always build variable payloads from key/value pairs so name is never null","Validate variable names client-side before posting","Use a typed DTO with a required name field"],"tags":["rest-api","variables","validation","external-worker"],"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-18T11:17:12.947Z"}