flowable/flowable-engine · error · FlowableException

Invalid usage of ${TYPE} job handler, variable scope is of t

Error message

Invalid usage of ${TYPE} job handler, variable scope is of type ${variableScope.getClass()}

What it means

AsyncLeaveActivePlanItemInstanceJobHandler requires the variable scope passed by the job executor to be a CaseInstanceEntity; any other VariableScope type means the job was invoked in an invalid way. The handler throws FlowableException naming the actual scope class so miswiring is visible immediately.

Source

Thrown at modules/flowable-cmmn-engine/src/main/java/org/flowable/cmmn/engine/impl/job/AsyncLeaveActivePlanItemInstanceJobHandler.java:91

                    if (errorCode != null) {
                        String errorMessage = jsonConfiguration.path(OperationSerializationMetadata.FIELD_ERROR_MESSAGE).stringValue(null);
                        CmmnFault reconstructedError = errorMessage != null ? new CmmnFault(errorCode, errorMessage) : new CmmnFault(errorCode);
                        CommandContextUtil.getAgenda(commandContext).planFailPlanItemInstanceOperation(planItemInstanceEntity, reconstructedError);
                    } else {
                        CommandContextUtil.getAgenda(commandContext).planFailPlanItemInstanceOperation(planItemInstanceEntity);
                    }

                } else {
                    throw new FlowableException("Programmatic error: unsupported transition " + transition + " for " + planItemInstanceEntity);

                }

            } catch (Exception e) {
                throw new FlowableException("Could not deserialize job configuration", e);
            }

        } else {
            throw new FlowableException("Invalid usage of " + TYPE + " job handler, variable scope is of type " + variableScope.getClass());
        }
    }

}

View on GitHub (pinned to d6d39ce1c6)

Solutions

  1. Verify the async job is created for a CMMN case instance (CaseInstanceEntity scope), not a BPMN process scope.
  2. If you create these jobs via custom code, resolve and pass the CaseInstanceEntity when scheduling the job.
  3. Check any subclass/override of the job handler dispatch logic that may supply the wrong variable scope.
  4. Confirm you are not mixing flowable-engine and flowable-cmmn-engine job handlers on shared job definitions.

Example fix

// before: handler invoked with a generic scope
jobHandler.execute(job, caseInstanceId, taskEntity, commandContext);
// after
CaseInstanceEntity caseInstance = CommandContextUtil.getCaseInstanceEntityManager(commandContext).findById(caseInstanceId);
jobHandler.execute(job, caseInstanceId, caseInstance, commandContext);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!(scope instanceof CaseInstanceEntity)) {
    throw new IllegalArgumentException("AsyncLeaveActivePlanItemInstanceJobHandler requires CaseInstanceEntity scope");
}

Type guard

boolean validScope(VariableScope scope) {
    return scope instanceof CaseInstanceEntity;
}

Try / catch

try {
    // custom dispatch of job handler
} catch (FlowableException e) {
    if (e.getMessage() != null && e.getMessage().contains("variable scope is of type")) {
        throw new IllegalStateException("Job attached to wrong scope; re-create job against the case instance", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: execute(job, caseInstanceId, variableScope, commandContext) receives a variableScope whose class is not CaseInstanceEntity — e.g. the job was created/attached to the wrong scope or a custom job/handler dispatches it with a process or task variable scope.

Common situations: Custom job creation code binding the async leave job to the wrong entity; engine customization or subclassed job dispatch passing the wrong scope; mixing BPMN (ProcessInstance) and CMMN (CaseInstance) job handling in a shared executor setup.

Related errors


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