{"record":{"id":"9927520715099cba","repo":"flowable/flowable-engine","slug":"externalworkerjob-is-not-bpmn-scoped-this-comma","errorCode":null,"errorMessage":"{externalWorkerJob} is not bpmn scoped. This command can only handle bpmn scoped external worker jobs","messagePattern":"(.+?) is not bpmn scoped\\. This command can only handle bpmn scoped external worker jobs","errorType":"exception","errorClass":"FlowableException","httpStatus":null,"severity":"error","filePath":"modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AbstractExternalWorkerJobCmd.java","lineNumber":50,"sourceCode":" * @author Filip Hrisafov\n */\npublic abstract class AbstractExternalWorkerJobCmd implements Command<Void> {\n\n    protected final String externalJobId;\n    protected final String workerId;\n    protected final JobServiceConfiguration jobServiceConfiguration;\n\n    protected AbstractExternalWorkerJobCmd(String externalJobId, String workerId, JobServiceConfiguration jobServiceConfiguration) {\n        this.externalJobId = externalJobId;\n        this.workerId = workerId;\n        this.jobServiceConfiguration = jobServiceConfiguration;\n    }\n\n    @Override\n    public final Void execute(CommandContext commandContext) {\n        ExternalWorkerJobEntity externalWorkerJob = resolveJob(commandContext);\n        if (externalWorkerJob.getProcessInstanceId() == null) {\n            throw new FlowableException(externalWorkerJob + \" is not bpmn scoped. This command can only handle bpmn 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            new UnlockExclusiveJobCmd(externalWorkerJob, jobServiceConfiguration).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        jobServiceConfiguration.getJobManager().moveExternalWorkerJobToExecutableJob(externalWorkerJob);\n\n        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration(commandContext);","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-engine/src/main/java/org/flowable/engine/impl/cmd/AbstractExternalWorkerJobCmd.java#L32-L68","documentation":"AbstractExternalWorkerJobCmd.execute resolves the external worker job and requires it to be BPMN-scoped, detected via a non-null processInstanceId. Jobs belonging to other scopes (e.g. CMMN case instances) have no process instance id, so this FlowableException is thrown and the command's job logic is skipped.","triggerScenarios":"Executing an AcquireExternalWorkerJobsCmd-derived command such as CompleteExternalWorkerJobCmd or BpmnExternalWorkerJobCmd (complete/fail/release via JobService/ExternalWorkerJobAcquireService) passing the id of a job created by a CMMN case, not a BPMN process.","commonSituations":"A generic external worker client acquires jobs from both process and case engines and, without checking scope, calls the BPMN completion API with a CMMN-scoped job id; job ids cached from a previous mixed-scope acquisition.","solutions":["Use the case-worker command/API (cmmn engine's external worker job handling) for jobs whose processInstanceId is null.","Filter acquired jobs by scope before dispatching: only call BPMN-specific complete/fail commands when job.getScopeType()/processInstanceId indicates BPMN.","Fix the acquisition query to restrict to BPMN-scoped jobs only (correct scope filters in the acquire command)."],"exampleFix":"// before\njobService.complete(externalWorkerJob.getId(), workerId, variables); // job may be CMMN-scoped\n// after\nif (externalWorkerJob.getProcessInstanceId() != null) {\n    jobService.complete(externalWorkerJob.getId(), workerId, variables);\n} else {\n    caseService.complete(externalWorkerJob.getId(), workerId, variables);\n}","handlingStrategy":"type-guard","validationCode":"if (externalWorkerJob.getProcessInstanceId() == null) {\n    // route to CMMN handling instead of BPMN commands\n}","typeGuard":"boolean isBpmnScoped(ExternalWorkerJob job) {\n    return job.getProcessInstanceId() != null;\n}","tryCatchPattern":null,"preventionTips":["Check scopeType/processInstanceId before invoking BPMN-specific job commands","Separate BPMN and CMMN job handling in the worker client","Filter the acquisition query to BPMN-scoped jobs only"],"tags":["flowable","external-worker","bpmn","scope-mismatch"],"backgroundTag":"unsupported-operation","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"}