flowable/flowable-engine · error · FlowableIllegalArgumentException
worker id must not be empty
Error message
worker id must not be empty
What it means
UnacquireAllExternalWorkerJobsForWorkerCmd.execute throws this FlowableIllegalArgumentException when workerId is null or empty. The command needs a worker id to find and release all externally acquired jobs belonging to that worker, so an empty id makes the operation impossible. It is fail-fast validation before querying the external worker job entity manager.
Solutions
- Configure a stable, non-empty worker id before starting the external worker
- Guard the call site: only call unacquire when workerId is present
- Fix config/property loading that yields an empty worker id
Example fix
// before
externalWorkerJobService.unacquireAllExternalWorkerJobsForWorker(workerId, tenantId);
// after
if (workerId != null && !workerId.isBlank()) {
externalWorkerJobService.unacquireAllExternalWorkerJobsForWorker(workerId, tenantId);
} else {
logger.warn("Skip unacquire: worker id not set");
} Defensive patterns
Strategy: validation
Validate before calling
if (workerId == null || workerId.isBlank()) {
throw new IllegalStateException("worker id must be configured before unacquire");
} Prevention
- Set a persistent non-empty worker id in external worker configuration
- Fail fast at startup if the worker id is missing
- Only call shutdown-cleanup paths after identity is initialized
When it happens
Trigger: Calling JobService/unacquireAllExternalWorkerJobsForWorker(workerId, tenantId) with workerId null or ""; a worker client whose id was never configured (missing worker-id property) invoking cleanup on shutdown.
Common situations: External worker configuration where the worker id property is missing or blank; passing a variable initialized from a failed lookup; code refactoring dropped the assignment of the worker id.
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
- at least one of userId or groups must be provided
- Cannot combine onlyBpmn() with onlyCmmn() in the same query
- Cannot combine onlyCmmn() with onlyBpmn() in the same query
- Cannot combine scopeType(String) with onlyBpmn() in the…
- Cannot combine scopeType(String) with onlyCmmn() in the…
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/df974cdd92fa0753.
Report an issue: GitHub.
Appendix: source
Thrown at modules/flowable-job-service/src/main/java/org/flowable/job/service/impl/cmd/UnacquireAllExternalWorkerJobsForWorkerCmd.java:40
import org.flowable.job.service.impl.persistence.entity.ExternalWorkerJobEntity;
import org.flowable.job.service.impl.persistence.entity.ExternalWorkerJobEntityManager;
public class UnacquireAllExternalWorkerJobsForWorkerCmd implements Command<Void> {
protected final String workerId;
protected final String tenantId;
protected final JobServiceConfiguration jobServiceConfiguration;
public UnacquireAllExternalWorkerJobsForWorkerCmd(String workerId, String tenantId, JobServiceConfiguration jobServiceConfiguration) {
this.workerId = workerId;
this.tenantId = tenantId;
this.jobServiceConfiguration = jobServiceConfiguration;
}
@Override
public Void execute(CommandContext commandContext) {
if (StringUtils.isEmpty(workerId)) {
throw new FlowableIllegalArgumentException("worker id must not be empty");
}
ExternalWorkerJobEntityManager externalWorkerJobEntityManager = jobServiceConfiguration.getExternalWorkerJobEntityManager();
List<ExternalWorkerJobEntity> jobEntities = externalWorkerJobEntityManager.findJobsByWorkerId(workerId);
if (!jobEntities.isEmpty()) {
if (StringUtils.isNotEmpty(tenantId)) {
for (ExternalWorkerJobEntity externalWorkerJob : jobEntities) {
if (!tenantId.equals(externalWorkerJob.getTenantId())) {
throw new FlowableIllegalArgumentException("provided worker id has external worker jobs from different tenant.");
}
}
}
for (ExternalWorkerJobEntity externalWorkerJob : jobEntities) {
if (externalWorkerJob.isExclusive()) {
new UnlockExclusiveJobCmd(externalWorkerJob, jobServiceConfiguration).execute(commandContext);View on GitHub (pinned to d6d39ce1c6)