flowable/flowable-engine · error · FlowableIllegalArgumentException
Can only complete BPMN or CMMN external job. Job with id '${
Error message
Can only complete BPMN or CMMN external job. Job with id '${jobId}' is from scope '${scopeType}' What it means
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.
Source
Thrown at modules/flowable-external-job-rest/src/main/java/org/flowable/external/job/rest/service/api/acquire/ExternalWorkerAcquireJobResource.java:138
.variables(extractVariables(request.getVariables()))
.complete();
} else {
throw new FlowableException("Cannot complete BPMN job. There is no BPMN engine available");
}
} else if (ScopeTypes.CMMN.equals(job.getScopeType())) {
if (cmmnManagementService != null) {
if (restApiInterceptor != null) {
restApiInterceptor.completeExternalWorkerJob(job, request);
}
cmmnManagementService.createCmmnExternalWorkerTransitionBuilder(job.getId(), workerId)
.variables(extractVariables(request.getVariables()))
.complete();
} else {
throw new FlowableException("Cannot complete CMMN job. There is no CMMN engine available");
}
} else {
throw new FlowableIllegalArgumentException(
"Can only complete BPMN or CMMN external job. Job with id '" + jobId + "' is from scope '" + job.getScopeType() + "'");
}
return ResponseEntity.noContent().build();
}
@ApiOperation(value = "Complete an External Worker Job with a BPMN Error", code = 204, tags = { "Acquire and Execute" })
@ApiResponses({
@ApiResponse(code = 204, message = "Indicates the job was successfully completed."),
@ApiResponse(code = 400, message = "Indicates the request was invalid."),
@ApiResponse(code = 403, message = "Indicates the user does not have the rights complete the job."),
@ApiResponse(code = 404, message = "Indicates the job does not exist."),
})
@PostMapping(value = "/acquire/jobs/{jobId}/bpmnError", produces = "application/json")
public ResponseEntity<?> bpmnErrorJob(@PathVariable String jobId, @RequestBody ExternalWorkerJobErrorRequest request) {
String workerId = request.getWorkerId();
if (StringUtils.isEmpty(workerId)) {
throw new FlowableIllegalArgumentException("workerId is required");View on GitHub (pinned to d6d39ce1c6)
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.
Example fix
// before // job row with SCOPE_TYPE_ = 'custom' -> 400 // after // recreate the job through a supported BPMN/CMMN service task so // scopeType is 'bpmn' or 'cmmn', then complete it
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check scope type if the API exposes it
if (job.getScopeType() == null || !("bpmn".equals(job.getScopeType()) || "cmmn".equals(job.getScopeType()))) {
throw new IllegalStateException("Unexpected scopeType: " + job.getScopeType());
} Try / catch
try {
restClient.complete(jobId, request);
} catch (HttpClientErrorException.BadRequest e) {
log.error("Job {} has unsupported scope; inspect ACT_RU_EXTERNAL_JOB", jobId);
} Prevention
- 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.
When it happens
Trigger: 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'.
Common situations: 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.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- lockDuration is required
- topic is required
- workerId is required
- Multipart request is required
- Multipart request with file content is required
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/2709a747fb1a5cb4.
Report an issue: GitHub.