flowable/flowable-engine · error · PvmException

not in an activity- or process definition scope. (but in a…

Error message

not in an activity- or process definition scope. (but in a transition scope)

What it means

PvmException thrown by the two-argument executionListener(eventName, listener) when the builder is currently in a transition scope. Event-named listeners can only be attached to activity or process-definition scopes, not transitions. This complements error 4742 which covers the reverse case.

Solutions

  1. Attach the listener inside an activity or process scope: call executionListener(eventName, listener) right after startActivity(...) or at the top (process) level.
  2. For transition-scoped listeners use the single-argument executionListener(listener) overload.
  3. Move the call before the startTransition(...) invocation in the builder chain.

Example fix

// before
builder.startTransition("b").executionListener("start", myListener); // invalid in transition scope
// after
builder.startTransition("b").executionListener(myListener);
// or attach named listener at process/activity level:
builder.executionListener("end", myListener);
Defensive patterns

Strategy: validation

Validate before calling

boolean inTransition = lastBuilderCallWasStartTransition;
if (inTransition) {
  throw new IllegalStateException("executionListener(eventName, listener) is invalid inside a transition scope");
}
builder.executionListener(eventName, listener);

Try / catch

try {
  builder.executionListener(eventName, listener);
} catch (PvmException e) {
  if (e.getMessage() != null && e.getMessage().contains("transition scope")) {
    builder.executionListener(listener); // transition-scoped overload instead
  }
}

Prevention

When it happens

Trigger: Calling executionListener(eventName, listener) immediately after startTransition(...) while 'transition' is still set.

Common situations: Fluent-builder misuse: adding an event-named listener right after opening a transition instead of before it or inside an activity scope.

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/3aeb0f8eac28cf4e. Report an issue: GitHub.

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/ProcessDefinitionBuilder.java:150

    public ProcessDefinitionBuilder scope() {
        getActivity().setScope(true);
        return this;
    }

    public ProcessDefinitionBuilder executionListener(ExecutionListener executionListener) {
        if (transition != null) {
            transition.addExecutionListener(executionListener);
        } else {
            throw new PvmException("not in a transition scope");
        }
        return this;
    }

    public ProcessDefinitionBuilder executionListener(String eventName, ExecutionListener executionListener) {
        if (transition == null) {
            scopeStack.peek().addExecutionListener(eventName, executionListener);
        } else {
            throw new PvmException("not in an activity- or process definition scope. (but in a transition scope)");
        }
        return this;
    }
}

View on GitHub (pinned to d6d39ce1c6)