flowable/flowable-engine · error · FlowableCdiException

Cannot associate , already associated with . Disassociate…

Error message

Cannot associate , already associated with . Disassociate first!

What it means

setExecution() enforces one execution per scoped association: if the current CDI scope already holds an execution with a different id, re-associating without clearing first throws this FlowableCdiException ('Cannot associate X, already associated with Y. Disassociate first!').

Solutions

  1. Call businessProcess.disAssociate() before associating a different execution.
  2. End the conversation when a task/process interaction completes: @CompleteTask(endConversation = true).
  3. If the same execution is intended, verify ids match rather than re-associating (association is idempotent only for the same id).

Example fix

// before
businessProcess.associateExecution(newExecution);
// after
businessProcess.disAssociate();
businessProcess.associateExecution(newExecution);
Defensive patterns

Strategy: try-catch

Validate before calling

Execution current = /* track in scope */ null;
if (current != null && !current.getId().equals(newExecution.getId())) businessProcess.disAssociate();

Type guard

null

Try / catch

try { businessProcess.associateExecution(newExec); } catch (FlowableCdiException e) { businessProcess.disAssociate(); businessProcess.associateExecution(newExec); }

Prevention

When it happens

Trigger: Calling businessProcess.associateExecution(execB) while the same conversation/request scope still has execA associated; typical in long conversations where a second process interaction starts without disAssociate().

Common situations: Handling multiple process instances in one CDI conversation (e.g. user opens a second task without finishing the first); missing @CompleteTask(endConversation=true) so the association leaks across requests.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


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

Appendix: source

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

    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);
    }

    @Override
    public void disAssociate() {
        if (Context.getCommandContext() != null) {
            throw new FlowableCdiException("Cannot work with scoped associations inside command context.");
        }
        ScopedAssociation scopedAssociation = getScopedAssociation();
        if (scopedAssociation.getExecution() == null) {
            throw new FlowableException("Cannot disassociate execution, no " + scopedAssociation.getClass().getAnnotations()[0].annotationType().getSimpleName() + " execution associated. ");
        }
        if (LOGGER.isTraceEnabled()) {

View on GitHub (pinned to d6d39ce1c6)