flowable/flowable-engine · error · FlowableIllegalArgumentException
workerId must not be empty
Error message
workerId must not be empty
What it means
FlowableIllegalArgumentException thrown by resolveJob when the workerId passed to the external worker command is null or empty. The workerId identifies which worker is acting on the job and is required for identity-link bookkeeping and validation.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AbstractExternalWorkerJobCmd.java:78
}
protected abstract void runJobLogic(ExternalWorkerJobEntity externalWorkerJob, CommandContext commandContext);
protected void moveExternalWorkerJobToExecutableJob(ExternalWorkerJobEntity externalWorkerJob, CommandContext commandContext) {
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
cmmnEngineConfiguration.getJobServiceConfiguration().getJobManager().moveExternalWorkerJobToExecutableJob(externalWorkerJob);
cmmnEngineConfiguration.getIdentityLinkServiceConfiguration().getIdentityLinkService()
.deleteIdentityLinksByScopeIdAndType(externalWorkerJob.getCorrelationId(), ScopeTypes.EXTERNAL_WORKER);
}
protected ExternalWorkerJobEntity resolveJob(CommandContext commandContext) {
if (StringUtils.isEmpty(externalJobId)) {
throw new FlowableIllegalArgumentException("externalJobId must not be empty");
}
if (StringUtils.isEmpty(workerId)) {
throw new FlowableIllegalArgumentException("workerId must not be empty");
}
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
ExternalWorkerJobEntityManager externalWorkerJobEntityManager = cmmnEngineConfiguration.getJobServiceConfiguration().getExternalWorkerJobEntityManager();
ExternalWorkerJobEntity job = externalWorkerJobEntityManager.findById(externalJobId);
if (job == null) {
throw new FlowableObjectNotFoundException("No External Worker job found for id: " + externalJobId, ExternalWorkerJobEntity.class);
}
if (!Objects.equals(workerId, job.getLockOwner())) {
throw new FlowableIllegalArgumentException(workerId + " does not hold a lock on the requested job");
}
return job;
}
}View on GitHub (pinned to d6d39ce1c6)
Solutions
- Pass the same workerId used during job acquisition into the completion/failure builder.
- Check application configuration so the worker id is populated (non-empty) at startup.
- Swap arguments if job id and worker id were transposed in the builder call.
Example fix
// before
cmmnExternalWorkerServiceProvider.completeBuilder("", externalJobId).complete();
// after
cmmnExternalWorkerServiceProvider.completeBuilder("order-worker-1", externalJobId).complete(); Defensive patterns
Strategy: validation
Validate before calling
if (workerId == null || workerId.isBlank())
throw new IllegalArgumentException("workerId must be configured before handling external worker jobs"); Try / catch
try { completeBuilder(workerId, externalJobId).complete(); }
catch (FlowableIllegalArgumentException e) { if (e.getMessage().equals("workerId must not be empty")) { reloadWorkerConfig(); } } Prevention
- Validate worker id at application startup, not per job
- Use named builder parameters to avoid transposing workerId and externalJobId
When it happens
Trigger: Calling completeBuilder/failureBuilder with an empty workerId, e.g., workerId field never set from configuration or the acquire response.
Common situations: Worker application missing its configured worker id (empty env var/config key); passing job id where workerId is expected due to argument order confusion.
Understand the failure class
Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.
Related errors
- externalJobId must not be empty
- There can only be one reactivation listener on a case model,
- A 'maxInstanceCount' on a repetition rule with value '0' is
- Job {jobId} parent is not CMMN case
- no topic expression configured for
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/c97dbd9503e57375.
Report an issue: GitHub.