flowable/flowable-engine · error · FlowableException
${externalWorkerJob} is not cmmn scoped. This command can on
Error message
${externalWorkerJob} is not cmmn scoped. This command can only handle cmmn scoped external worker jobs What it means
FlowableException thrown in AbstractExternalWorkerJobCmd.execute after resolving the job: the job's scopeType is not 'cmmn', meaning the external worker job belongs to a BPMN (process) scope while this CMMN command is used against it. The command is final and hard-fails before running job logic.
Source
Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AbstractExternalWorkerJobCmd.java:48
/**
* @author Filip Hrisafov
*/
public abstract class AbstractExternalWorkerJobCmd implements Command<Void> {
protected final String externalJobId;
protected final String workerId;
protected AbstractExternalWorkerJobCmd(String externalJobId, String workerId) {
this.externalJobId = externalJobId;
this.workerId = workerId;
}
@Override
public final Void execute(CommandContext commandContext) {
ExternalWorkerJobEntity externalWorkerJob = resolveJob(commandContext);
if (!ScopeTypes.CMMN.equals(externalWorkerJob.getScopeType())) {
throw new FlowableException(externalWorkerJob + " is not cmmn scoped. This command can only handle cmmn scoped external worker jobs");
}
runJobLogic(externalWorkerJob, commandContext);
if (externalWorkerJob.isExclusive()) {
// Part of the same transaction to avoid a race condition with the
// potentially new jobs (wrt process instance locking) that are created
// during the execution of the original job
CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);
new UnlockExclusiveJobCmd(externalWorkerJob, cmmnEngineConfiguration.getJobServiceConfiguration()).execute(commandContext);
}
return null;
}
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);View on GitHub (pinned to d6d39ce1c6)
Solutions
- Route the job to the correct command: use the BPMN external worker task command for process-scoped jobs.
- Verify the job's scopeType before dispatching (inspect the external worker job entity).
- Separate worker polling/registration per engine (cmmn vs process) so ids cannot be mixed.
Example fix
// before cmmnExternalWorkerTaskComplete(externalJobId); // job is process-scoped // after processExternalWorkerTaskComplete(externalJobId); // use BPMN command for process-scoped jobs
Defensive patterns
Strategy: try-catch
Validate before calling
ExternalWorkerJob job = externalWorkerJobQuery jobId(id).singleResult(); if (job != null && !"cmmn".equals(job.getScopeType())) routeToProcessEngine(job);
Type guard
function isCmmnScoped(job) { return job != null && "cmmn" === job.getScopeType(); } Try / catch
try { cmmnCommand.execute(); }
catch (FlowableException e) { if (e.getMessage().endsWith("is not cmmn scoped")) { dispatchToBpmn(jobId); } } Prevention
- Tag jobs with scopeType at acquisition and route completions to the matching engine
- Keep separate worker registrations for BPMN and CMMN external tasks
When it happens
Trigger: Executing a CMMN external-worker command (complete/benefit/failure) passing an externalJobId that actually references a process-scoped external worker job created by a BPMN service task.
Common situations: Sharing worker/job id bookkeeping between BPMN and CMMN engines; copy-pasting job ids between services; workers polling a combined job queue and routing ids to the wrong engine's command API.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Can only complete BPMN external job with a BPMN error. Job w
- Can only terminate CMMN external job. Job with id '${jobId}'
- no topic expression configured for
- Expression
- externalJobId must not be empty
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/19bcf23bb0000194.
Report an issue: GitHub.