flowable/flowable-engine · error · FlowableCdiException

Cannot associate with execution: null

Error message

Cannot associate with execution: null

What it means

DefaultContextAssociationManager.setExecution(Execution) associates the current CDI scope with a process execution. Passing null is rejected outright with this FlowableCdiException because a null association is meaningless — use disAssociate() to clear an existing association.

Solutions

  1. Verify the execution exists before associating: runtimeService.createExecutionQuery().executionId(id).singleResult() != null.
  2. Call businessProcess.disAssociate() instead of passing null to clear the current association.
  3. Check you are passing the process instance id / execution id you actually intend (not a task id).

Example fix

// before
businessProcess.associateExecution(executionQuery.singleResult()); // may be null
// after
Execution e = executionQuery.singleResult();
if (e != null) businessProcess.associateExecution(e);
Defensive patterns

Strategy: validation

Validate before calling

Execution e = runtimeService.createExecutionQuery().executionId(executionId).singleResult();
if (e == null) throw new IllegalArgumentException("execution " + executionId + " not found");

Type guard

static boolean isNonNullExecution(Execution ex) { return ex != null && ex.getId() != null; }

Try / catch

try { businessProcess.associateExecution(e); } catch (FlowableCdiException e) { /* null guard failed; resolve execution again */ }

Prevention

When it happens

Trigger: Calling businessProcess.associateExecution(null) / setExecution(null), typically when the execution lookup (e.g. runtimeService.createExecutionQuery()...singleResult()) returned null and its result was passed straight through.

Common situations: Execution already ended so the query for it returns null; typo'd execution/business-key; using process instance id where an execution id is required and vice versa.

Related errors


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

Appendix: source

Thrown at modules/flowable-cdi/src/main/java/org/flowable/cdi/impl/context/DefaultContextAssociationManager.java:145

     * Override to add different / additional contexts.
     *
     * @return a list of {@link Scope}-types, which are used in the given order to resolve the broadest active context (@link #getBroadestActiveContext()})
     */
    protected List<Class<? extends ScopedAssociation>> getAvailableScopedAssociationClasses() {
        ArrayList<Class<? extends ScopedAssociation>> scopeTypes = new ArrayList<>();
        scopeTypes.add(ConversationScopedAssociation.class);
        scopeTypes.add(RequestScopedAssociation.class);
        return scopeTypes;
    }

    protected ScopedAssociation getScopedAssociation() {
        return ProgrammaticBeanLookup.lookup(getBroadestActiveContext(), beanManager);
    }

    @Override
    public void setExecution(Execution execution) {
        if (execution == null) {
            throw new FlowableCdiException("Cannot associate with execution: null");
        }

        if (Context.getCommandContext() != null) {
            throw new FlowableCdiException("Cannot work with scoped associations inside command context.");
        }

        ScopedAssociation scopedAssociation = getScopedAssociation();
        Execution associatedExecution = scopedAssociation.getExecution();
        if (associatedExecution != null && !associatedExecution.getId().equals(execution.getId())) {
            throw new FlowableCdiException("Cannot associate " + execution + ", already associated with " + associatedExecution + ". Disassociate first!");
        }

        if (LOGGER.isTraceEnabled()) {
            LOGGER.trace("Associating {} (@{})", execution, scopedAssociation.getClass().getAnnotations()[0].annotationType().getSimpleName());
        }
        scopedAssociation.setExecution(execution);
    }

View on GitHub (pinned to d6d39ce1c6)