{"record":{"id":"f99b61f72656e661","repo":"flowable/flowable-engine","slug":"worker-id-is-required","errorCode":null,"errorMessage":"worker id is required","messagePattern":"worker id 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/ExternalWorkerUnacquireJobResource.java","lineNumber":57,"sourceCode":"\n    public ExternalWorkerUnacquireJobResource(ExternalJobRestResponseFactory restResponseFactory) {\n        this.restResponseFactory = restResponseFactory;\n    }\n\n    @ApiOperation(value = \"Unacquire External Worker Jobs\", tags = { \"Unacquire\" })\n    @ApiResponses({\n            @ApiResponse(code = 204, message = \"Indicates the jobs were unacquired.\"),\n            @ApiResponse(code = 400, message = \"Indicates the request was invalid.\"),\n            @ApiResponse(code = 403, message = \"Indicates the user does not have the rights to unacquire the jobs.\"),\n    })\n    @PostMapping(value = \"/unacquire/jobs\", produces = \"application/json\")\n    public ResponseEntity<?> unacquireJobs(@RequestBody UnacquireExternalWorkerJobsRequest request) {\n        if (restApiInterceptor != null) {\n            restApiInterceptor.accessUnacquireExternalWorkerJobs(request);\n        }\n\n        if (StringUtils.isEmpty(request.getWorkerId())) {\n            throw new FlowableIllegalArgumentException(\"worker id is required\");\n        }\n\n        unaquireExternalWorkerJobs(request.getWorkerId(), request.getTenantId());\n        \n        return ResponseEntity.noContent().build();\n    }\n\n    @ApiOperation(value = \"Unaquire an External Worker Job\", code = 204, tags = { \"Unacquire\" })\n    @ApiResponses({\n            @ApiResponse(code = 204, message = \"Indicates the job was successfully unaquired.\"),\n            @ApiResponse(code = 400, message = \"Indicates the request was invalid.\"),\n            @ApiResponse(code = 403, message = \"Indicates the user does not have the rights to unacquire the job.\"),\n            @ApiResponse(code = 404, message = \"Indicates the job does not exist.\"),\n    })\n    @PostMapping(value = \"/unacquire/jobs/{jobId}\", produces = \"application/json\")\n    public ResponseEntity<?> unaquireJob(@PathVariable String jobId, @RequestBody UnacquireExternalWorkerJobsRequest request) {\n        String workerId = request.getWorkerId();\n        if (StringUtils.isEmpty(workerId)) {","sourceCodeStart":39,"sourceCodeEnd":75,"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/ExternalWorkerUnacquireJobResource.java#L39-L75","documentation":"FlowableIllegalArgumentException thrown by unacquireJobs when the request body has an empty or null workerId. The worker id identifies which worker's locks to release, so it is mandatory. The check runs before any engine interaction.","triggerScenarios":"POST /external-worker-job/unacquire/jobs with a body missing 'workerId' or with workerId=\"\" (UnacquireExternalWorkerJobsRequest without workerId).","commonSituations":"Clients that only send tenantId; DTOs deserialized from JSON lacking the field; test scripts posting empty bodies.","solutions":["Include the workerId field in the unacquire request body.","Validate workerId is non-blank on the client before calling the endpoint.","Check the code constructing UnacquireExternalWorkerJobsRequest to ensure it copies the worker id."],"exampleFix":"// before\nPOST /external-worker-job/unacquire/jobs {\"tenantId\":\"t1\"}\n// after\nPOST /external-worker-job/unacquire/jobs {\"workerId\":\"worker-1\",\"tenantId\":\"t1\"}","handlingStrategy":"validation","validationCode":"if (workerId == null || workerId.isBlank()) { throw new IllegalArgumentException(\"workerId is required\"); }","typeGuard":"boolean validWorkerId(String id) { return id != null && !id.isBlank(); }","tryCatchPattern":"try { unacquireJobs(request); } catch (FlowableIllegalArgumentException e) { if (e.getMessage().equals(\"worker id is required\")) { supplyWorkerIdAndRetry(); } else { throw e; } }","preventionTips":["Always send workerId in the unacquire request body","Validate the request DTO before sending","Use a stable configured worker id"],"tags":["rest-api","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"}