flowable/flowable-engine · error · FlowableException
Invalid usage of job handler, variable scope is of type
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.
Solutions
- Verify the async job is created for a CMMN case instance (CaseInstanceEntity scope), not a BPMN process scope.
- If you create these jobs via custom code, resolve and pass the CaseInstanceEntity when scheduling the job.
- Check any subclass/override of the job handler dispatch logic that may supply the wrong variable scope.
- 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
- Create CMMN async jobs only against case instance scopes
- Do not subclass/redirect job handler dispatch between BPMN and CMMN engines
- Add integration tests running async jobs end-to-end after engine customizations
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
- Invalid usage of async_activate job handler, variable scope…
- Could not deserialize job configuration
- Could not evaluate collection for repetition rule on plan…
- Delegate expression did not resolve to an implementation of
- Delegate expression did not resolve to an implementation of
AI-assisted analysis of flowable/flowable-engine@d6d39ce1c6 (2026-09-11).
Data as JSON: /api/errors/4f5f65f6b2073522.
Report an issue: GitHub.
Appendix: 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)