{"record":{"id":"2453ae26d0f5f642","repo":"flowable/flowable-engine","slug":"workerid-must-not-be-empty-2453ae","errorCode":null,"errorMessage":"workerId must not be empty","messagePattern":"workerId must not be empty","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AbstractExternalWorkerJobCmd.java","lineNumber":79,"sourceCode":"    }\n\n    protected abstract void runJobLogic(ExternalWorkerJobEntity externalWorkerJob, CommandContext commandContext);\n\n    protected void moveExternalWorkerJobToExecutableJob(ExternalWorkerJobEntity externalWorkerJob, CommandContext commandContext) {\n        jobServiceConfiguration.getJobManager().moveExternalWorkerJobToExecutableJob(externalWorkerJob);\n\n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);\n        processEngineConfiguration.getIdentityLinkServiceConfiguration().getIdentityLinkService()\n                .deleteIdentityLinksByScopeIdAndType(externalWorkerJob.getCorrelationId(), ScopeTypes.EXTERNAL_WORKER);\n    }\n\n    protected ExternalWorkerJobEntity resolveJob(CommandContext commandContext) {\n        if (StringUtils.isEmpty(externalJobId)) {\n            throw new FlowableIllegalArgumentException(\"externalJobId must not be empty\");\n        }\n\n        if (StringUtils.isEmpty(workerId)) {\n            throw new FlowableIllegalArgumentException(\"workerId must not be empty\");\n        }\n\n        ExternalWorkerJobEntityManager externalWorkerJobEntityManager = jobServiceConfiguration.getExternalWorkerJobEntityManager();\n\n        ExternalWorkerJobEntity job = externalWorkerJobEntityManager.findById(externalJobId);\n\n        if (job == null) {\n            throw new FlowableObjectNotFoundException(\"No External Worker job found for id: \" + externalJobId, ExternalWorkerJobEntity.class);\n        }\n\n        if (!Objects.equals(workerId, job.getLockOwner())) {\n            throw new FlowableIllegalArgumentException(workerId + \" does not hold a lock on the requested job\");\n        }\n\n        return job;\n    }\n}\n","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AbstractExternalWorkerJobCmd.java#L61-L97","documentation":"The same resolveJob validation path also requires a workerId. The workerId identifies which worker holds the lock on the acquired job; without it lock ownership cannot be verified, so a FlowableIllegalArgumentException is thrown.","triggerScenarios":"Invoking complete/fail/release/unlock commands with workerId null or empty, even when externalJobId is valid.","commonSituations":"Worker identity not propagated into the command (config lost the workerId); multiple workers sharing a client that hardcodes or drops the worker id; refactoring changed the workerId variable's initialization.","solutions":["Pass the same workerId that was used when acquiring/locking the job into the command.","Ensure each worker instance sets a unique, non-empty workerId at startup and carries it through all job commands.","Add a client-side check that workerId is non-blank before calling the job service."],"exampleFix":"// before\nexternalWorkerJobService.complete(jobId, workerId, variables); // workerId empty\n// after\nString workerId = config.getWorkerId(); // e.g. worker-42 set at startup\nexternalWorkerJobService.complete(jobId, workerId, variables);","handlingStrategy":"validation","validationCode":"if (workerId == null || workerId.isBlank()) {\n    throw new IllegalArgumentException(\"workerId required\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Assign a unique non-empty workerId at worker startup","Propagate workerId via a single config object used in all job commands","Assert workerId presence in integration tests"],"tags":["flowable","external-worker","argument-validation"],"backgroundTag":"empty-required-field","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"}