{"record":{"id":"2709a747fb1a5cb4","repo":"flowable/flowable-engine","slug":"can-only-complete-bpmn-or-cmmn-external-job-job-w","errorCode":null,"errorMessage":"Can only complete BPMN or CMMN external job. Job with id '${jobId}' is from scope '${scopeType}'","messagePattern":"Can only complete BPMN or CMMN external job\\. Job with id '(.+?)' is from scope '(.+?)'","errorType":"validation","errorClass":"FlowableIllegalArgumentException","httpStatus":400,"severity":"error","filePath":"modules/flowable-external-job-rest/src/main/java/org/flowable/external/job/rest/service/api/acquire/ExternalWorkerAcquireJobResource.java","lineNumber":138,"sourceCode":"                        .variables(extractVariables(request.getVariables()))\n                        .complete();\n            } else {\n                throw new FlowableException(\"Cannot complete BPMN job. There is no BPMN engine available\");\n            }\n        } else if (ScopeTypes.CMMN.equals(job.getScopeType())) {\n            if (cmmnManagementService != null) {\n                if (restApiInterceptor != null) {\n                    restApiInterceptor.completeExternalWorkerJob(job, request);\n                }\n\n                cmmnManagementService.createCmmnExternalWorkerTransitionBuilder(job.getId(), workerId)\n                        .variables(extractVariables(request.getVariables()))\n                        .complete();\n            } else {\n                throw new FlowableException(\"Cannot complete CMMN job. There is no CMMN engine available\");\n            }\n        } else {\n            throw new FlowableIllegalArgumentException(\n                    \"Can only complete BPMN or CMMN external job. Job with id '\" + jobId + \"' is from scope '\" + job.getScopeType() + \"'\");\n        }\n\n        return ResponseEntity.noContent().build();\n    }\n\n    @ApiOperation(value = \"Complete an External Worker Job with a BPMN Error\", code = 204, tags = { \"Acquire and Execute\" })\n    @ApiResponses({\n            @ApiResponse(code = 204, message = \"Indicates the job was successfully completed.\"),\n            @ApiResponse(code = 400, message = \"Indicates the request was invalid.\"),\n            @ApiResponse(code = 403, message = \"Indicates the user does not have the rights complete the job.\"),\n            @ApiResponse(code = 404, message = \"Indicates the job does not exist.\"),\n    })\n    @PostMapping(value = \"/acquire/jobs/{jobId}/bpmnError\", produces = \"application/json\")\n    public ResponseEntity<?> bpmnErrorJob(@PathVariable String jobId, @RequestBody ExternalWorkerJobErrorRequest request) {\n        String workerId = request.getWorkerId();\n        if (StringUtils.isEmpty(workerId)) {\n            throw new FlowableIllegalArgumentException(\"workerId is required\");","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/flowable/flowable-engine/blob/d6d39ce1c69ff244f2d9dc6af756a9b95e865586/modules/flowable-external-job-rest/src/main/java/org/flowable/external/job/rest/service/api/acquire/ExternalWorkerAcquireJobResource.java#L120-L156","documentation":"FlowableIllegalArgumentException thrown in completeJob when the job's scopeType is neither BPMN nor CMMN (including null/unexpected values). The completion logic only knows how to route BPMN process jobs and CMMN case jobs. Results in HTTP 400.","triggerScenarios":"POST /external-worker/acquire/jobs/{jobId}/complete for a job whose SCOPE_TYPE_ column is null, empty, or a custom/unexpected value rather than 'bpmn' or 'cmmn'.","commonSituations":"Corrupted or manually inserted job rows; jobs created by a newer Flowable version with a scope type this REST version doesn't understand; a mismatch between REST module version and engine version in the same deployment.","solutions":["Inspect the job's scopeType in ACT_RU_EXTERNAL_JOB and fix corrupt data or delete the bogus row.","Align the external-job REST module version with the engine version so all scope types are recognized.","Ensure jobs are only created through the Flowable engine APIs, not direct SQL inserts.","If the job is genuinely invalid, use the terminate endpoint or remove it via ManagementService."],"exampleFix":"// before\n// job row with SCOPE_TYPE_ = 'custom' -> 400\n// after\n// recreate the job through a supported BPMN/CMMN service task so\n// scopeType is 'bpmn' or 'cmmn', then complete it","handlingStrategy":"try-catch","validationCode":"// pre-check scope type if the API exposes it\nif (job.getScopeType() == null || !(\"bpmn\".equals(job.getScopeType()) || \"cmmn\".equals(job.getScopeType()))) {\n    throw new IllegalStateException(\"Unexpected scopeType: \" + job.getScopeType());\n}","typeGuard":null,"tryCatchPattern":"try {\n    restClient.complete(jobId, request);\n} catch (HttpClientErrorException.BadRequest e) {\n    log.error(\"Job {} has unsupported scope; inspect ACT_RU_EXTERNAL_JOB\", jobId);\n}","preventionTips":["Keep REST module and engine versions aligned.","Never insert or mutate job rows with direct SQL.","Monitor for jobs with null SCOPE_TYPE_ via database checks."],"tags":["rest","external-worker","scope-type","validation"],"backgroundTag":"invalid-enum-value","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"}