{"record":{"id":"aecb12981e3a5157","repo":"flowable/flowable-engine","slug":"workerid-must-not-be-empty-aecb12","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-job-service/src/main/java/org/flowable/job/service/impl/cmd/AcquireExternalWorkerJobsCmd.java","lineNumber":65,"sourceCode":"        this.workerId = workerId;\n        this.numberOfJobs = numberOfJobs;\n        this.builder = builder;\n        this.jobServiceConfiguration = jobServiceConfiguration;\n    }\n\n    @Override\n    public List<AcquiredExternalWorkerJob> execute(CommandContext commandContext) {\n        String topic = builder.getTopic();\n        if (StringUtils.isEmpty(topic)) {\n            throw new FlowableIllegalArgumentException(\"topic must not be empty\");\n        }\n\n        if (numberOfJobs < 1) {\n            throw new FlowableIllegalArgumentException(\"requested number of jobs must not be smaller than 1\");\n        }\n\n        if (StringUtils.isEmpty(workerId)) {\n            throw new FlowableIllegalArgumentException(\"workerId must not be empty\");\n        }\n\n        ExternalWorkerJobEntityManager externalWorkerJobEntityManager = jobServiceConfiguration.getExternalWorkerJobEntityManager();\n        InternalJobManager internalJobManager = jobServiceConfiguration.getInternalJobManager();\n\n        List<ExternalWorkerJobEntity> jobs = externalWorkerJobEntityManager.findExternalJobsToExecute(builder, numberOfJobs);\n\n        int lockTimeInMillis = (int) builder.getLockDuration().abs().toMillis();\n        List<AcquiredExternalWorkerJob> acquiredJobs = new ArrayList<>(jobs.size());\n\n        for (ExternalWorkerJobEntity job : jobs) {\n            lockJob(commandContext, job, lockTimeInMillis);\n            Map<String, Object> variables = null;\n            if (internalJobManager != null) {\n                variables = internalJobManager.resolveVariablesForExternalWorkerJob(job);\n\n                if (job.isExclusive()) {\n                    internalJobManager.lockJobScope(job);","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/AcquireExternalWorkerJobsCmd.java#L47-L83","documentation":"Thrown by AcquireExternalWorkerJobsCmd.execute() when workerId is null or empty. The workerId identifies the locker: it is stored as lock owner on the jobs it acquires and later checked on completion, so Flowable requires a non-empty value at acquisition time.","triggerScenarios":"acquireAndLock(numberOfJobs, null, lockDuration); worker identity not initialized before the poll loop starts; configuration property for worker id missing so an empty string is passed.","commonSituations":"A worker started without its instance-name/worker-id property; race where the scheduler thread fires before configuration is bound; refactored code dropping the workerId parameter.","solutions":["Set a non-empty workerId before starting the acquisition loop and pass it to acquireAndLock","Validate worker configuration at startup: throw/fail deploy if workerId is blank","Generate a stable unique id (hostname + UUID) if instances don't have a natural identity"],"exampleFix":"// before\nbuilder.topic(topic).acquireAndLock(5, workerIdFromConfig, 60000); // empty config\n// after\nif (workerId == null || workerId.isEmpty()) {\n    throw new IllegalStateException(\"workerId must be configured\");\n}\nbuilder.topic(topic).acquireAndLock(5, workerId, 60000);","handlingStrategy":"validation","validationCode":"if (workerId == null || workerId.isEmpty()) {\n    throw new IllegalArgumentException(\"workerId must be set before acquiring jobs\");\n}","typeGuard":"boolean hasWorkerId(String id) { return id != null && !id.trim().isEmpty(); }","tryCatchPattern":"try {\n    acquireBuilder.topic(topic).acquireAndLock(numberOfJobs, workerId, lockDuration);\n} catch (FlowableIllegalArgumentException e) {\n    LOGGER.error(\"Acquire rejected: {}\", e.getMessage());\n}","preventionTips":["Initialize worker identity before starting the acquisition scheduler","Fail deployment/startup if the workerId property is missing or blank","Generate hostname+UUID based ids when instances lack natural identity"],"tags":["validation","flowable","acquire"],"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"}