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

  1. Inspect the job's scopeType in ACT_RU_EXTERNAL_JOB and fix corrupt data or delete the bogus row.
  2. Align the external-job REST module version with the engine version so all scope types are recognized.
  3. Ensure jobs are only created through the Flowable engine APIs, not direct SQL inserts.
  4. 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

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


AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11). Data as JSON: /api/errors/2709a747fb1a5cb4. Report an issue: GitHub.