flowable/flowable-engine · error · FlowableException

Cannot get process model: no current command context is…

Error message

Cannot get process model: no current command context is active

What it means

The process model for a process definition is resolved through the command context. ProcessDefinitionUtil.getProcess requires an active CommandContext (set up by engine services/commands); when Context.getCommandContext() is null it cannot access engine internals and throws this FlowableException. It typically means the method is being called outside an engine command/transaction.

Solutions

  1. Run the logic inside a command: processEngineConfiguration.getCommandExecutor().execute(new Command<Process>() { ... }) or managementService.executeCommand(...).
  2. Call public engine services (RepositoryService / RuntimeService) instead of internal ProcessDefinitionUtil to let the engine establish the command context.
  3. If in a custom async thread, propagate the CommandContext explicitly using Context/CommandContextUtil within a command wrapper.
  4. In tests, use the engine's command executor helper rather than static util access.

Example fix

// before
Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); // no context

// after
Process process = processEngine.getManagementService().executeCommand(
    commandContext -> ProcessDefinitionUtil.getProcess(processDefinitionId));
Defensive patterns

Strategy: try-catch

Validate before calling

// verify a command context is active before calling internals
if (Context.getCommandContext() == null) {
    // route through the engine instead of calling the util directly
}

Try / catch

try {
    Process p = managementService.executeCommand(
        ctx -> ProcessDefinitionUtil.getProcess(processDefinitionId));
} catch (FlowableException e) {
    if (e.getMessage().contains("no current command context")) {
        throw new IllegalStateException("Wrap internal calls in a command", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Calling getProcess(processDefinitionId) from non-command code such as a plain thread, a servlet filter, an application startup hook, or test code that has not wrapped the call in a command (e.g. managementService.executeCommand or an engine service call).

Common situations: Custom extensions calling internal util classes directly instead of going through engine services; asynchronous jobs or scheduled threads without command context propagation; unit tests invoking engine internals without CommandContextUtil initialization.

Related errors


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

Appendix: source

Thrown at modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/ProcessDefinitionUtil.java:83

    }

    public static ProcessDefinition getProcessDefinition(String processDefinitionId, boolean checkCacheOnly, ProcessEngineConfigurationImpl processEngineConfiguration) {
        if (checkCacheOnly) {
            ProcessDefinitionCacheEntry cacheEntry = processEngineConfiguration.getProcessDefinitionCache().get(processDefinitionId);
            if (cacheEntry != null) {
                return cacheEntry.getProcessDefinition();
            }
            return null;

        } else {
            // This will check the cache in the findDeployedProcessDefinitionById method
            return processEngineConfiguration.getDeploymentManager().findDeployedProcessDefinitionById(processDefinitionId);
        }
    }

    public static Process getProcess(String processDefinitionId) {
        if (Context.getCommandContext() == null) {
            throw new FlowableException("Cannot get process model: no current command context is active");
            
        } else if (CommandContextUtil.getProcessEngineConfiguration() == null) {
            return Flowable5Util.getFlowable5CompatibilityHandler().getProcessDefinitionProcessObject(processDefinitionId);

        } else {
            DeploymentManager deploymentManager = CommandContextUtil.getProcessEngineConfiguration().getDeploymentManager();

            // This will check the cache in the findDeployedProcessDefinitionById and resolveProcessDefinition method
            ProcessDefinition processDefinitionEntity = deploymentManager.findDeployedProcessDefinitionById(processDefinitionId);
            return deploymentManager.resolveProcessDefinition(processDefinitionEntity).getProcess();
        }
    }

    public static BpmnModel getBpmnModel(String processDefinitionId) {
        if (CommandContextUtil.getProcessEngineConfiguration() == null) {
            return Flowable5Util.getFlowable5CompatibilityHandler().getProcessDefinitionBpmnModel(processDefinitionId);

        } else {

View on GitHub (pinned to d6d39ce1c6)