{"record":{"id":"19bcf23bb0000194","repo":"flowable/flowable-engine","slug":"externalworkerjob-is-not-cmmn-scoped-this-comm","errorCode":null,"errorMessage":"${externalWorkerJob} is not cmmn scoped. This command can only handle cmmn scoped external worker jobs","messagePattern":"(.+?) is not cmmn scoped\\. This command can only handle cmmn scoped external worker jobs","errorType":"validation","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AbstractExternalWorkerJobCmd.java","lineNumber":48,"sourceCode":"/**\n * @author Filip Hrisafov\n */\npublic abstract class AbstractExternalWorkerJobCmd implements Command<Void> {\n\n    protected final String externalJobId;\n    protected final String workerId;\n\n    protected AbstractExternalWorkerJobCmd(String externalJobId, String workerId) {\n        this.externalJobId = externalJobId;\n        this.workerId = workerId;\n    }\n\n    @Override\n    public final Void execute(CommandContext commandContext) {\n        ExternalWorkerJobEntity externalWorkerJob = resolveJob(commandContext);\n\n        if (!ScopeTypes.CMMN.equals(externalWorkerJob.getScopeType())) {\n            throw new FlowableException(externalWorkerJob + \" is not cmmn scoped. This command can only handle cmmn scoped external worker jobs\");\n        }\n\n        runJobLogic(externalWorkerJob, commandContext);\n        if (externalWorkerJob.isExclusive()) {\n            // Part of the same transaction to avoid a race condition with the\n            // potentially new jobs (wrt process instance locking) that are created\n            // during the execution of the original job\n            CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n            new UnlockExclusiveJobCmd(externalWorkerJob, cmmnEngineConfiguration.getJobServiceConfiguration()).execute(commandContext);\n        }\n        return null;\n    }\n\n    protected abstract void runJobLogic(ExternalWorkerJobEntity externalWorkerJob, CommandContext commandContext);\n\n    protected void moveExternalWorkerJobToExecutableJob(ExternalWorkerJobEntity externalWorkerJob, CommandContext commandContext) {\n        CmmnEngineConfiguration cmmnEngineConfiguration = CommandContextUtil.getCmmnEngineConfiguration(commandContext);\n        cmmnEngineConfiguration.getJobServiceConfiguration().getJobManager().moveExternalWorkerJobToExecutableJob(externalWorkerJob);","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/cmd/AbstractExternalWorkerJobCmd.java#L30-L66","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ncmmnExternalWorkerTaskComplete(externalJobId); // job is process-scoped\n// after\nprocessExternalWorkerTaskComplete(externalJobId); // use BPMN command for process-scoped jobs","handlingStrategy":"try-catch","validationCode":"ExternalWorkerJob job = externalWorkerJobQuery jobId(id).singleResult();\nif (job != null && !\"cmmn\".equals(job.getScopeType())) routeToProcessEngine(job);","typeGuard":"function isCmmnScoped(job) { return job != null && \"cmmn\" === job.getScopeType(); }","tryCatchPattern":"try { cmmnCommand.execute(); }\ncatch (FlowableException e) { if (e.getMessage().endsWith(\"is not cmmn scoped\")) { dispatchToBpmn(jobId); } }","preventionTips":["Tag jobs with scopeType at acquisition and route completions to the matching engine","Keep separate worker registrations for BPMN and CMMN external tasks"],"tags":["cmmn","external-worker","scope-mismatch"],"backgroundTag":"invalid-state-transition","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"}