flowable/flowable-engine · error · PvmException

destinationActivityId is null

Error message

destinationActivityId is null

What it means

PvmException thrown by ProcessDefinitionBuilder.startTransition when the destination activity id argument is null. The builder records transitions whose destinations are resolved at build time by id, so a null id is invalid input that cannot be resolved later. It is a fail-fast argument validation to catch malformed process-definition construction early.

Solutions

  1. Pass a non-null destination activity id that matches an activity created via startActivity(...) on the same builder.
  2. Validate the id (e.g. from BPMN targetRef) before calling startTransition and skip or fail the transition creation if it is missing.
  3. Fix the upstream model/parse step that produced a null id.

Example fix

// before
builder.startTransition(taskDef.getDestinationId()); // may be null
// after
if (taskDef.getDestinationId() != null) {
  builder.startTransition(taskDef.getDestinationId());
} else {
  throw new IllegalArgumentException("transition target missing for " + taskDef.getId());
}
Defensive patterns

Strategy: validation

Validate before calling

if (destinationActivityId == null) {
  throw new IllegalArgumentException("destinationActivityId must be provided before startTransition()");
}
builder.startTransition(destinationActivityId);

Type guard

boolean hasDestination = destinationActivityId != null && !destinationActivityId.trim().isEmpty();

Prevention

When it happens

Trigger: Calling startTransition(null) or startTransition(null, someTransitionId) while building a PVM process definition programmatically.

Common situations: Programmatic process model construction where the destination id comes from a variable, map lookup, or parsed model that evaluated to null (e.g. missing targetRef in a converted BPMN model).

Related errors


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

Appendix: source

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

        processElement = scopeStack.peek();

        transition = null;

        return this;
    }

    public ProcessDefinitionBuilder initial() {
        processDefinition.setInitial(getActivity());
        return this;
    }

    public ProcessDefinitionBuilder startTransition(String destinationActivityId) {
        return startTransition(destinationActivityId, null);
    }

    public ProcessDefinitionBuilder startTransition(String destinationActivityId, String transitionId) {
        if (destinationActivityId == null) {
            throw new PvmException("destinationActivityId is null");
        }
        ActivityImpl activity = getActivity();
        transition = activity.createOutgoingTransition(transitionId);
        unresolvedTransitions.add(new Object[]{transition, destinationActivityId});
        processElement = transition;
        return this;
    }

    public ProcessDefinitionBuilder endTransition() {
        processElement = scopeStack.peek();
        transition = null;
        return this;
    }

    public ProcessDefinitionBuilder transition(String destinationActivityId) {
        return transition(destinationActivityId, null);
    }

View on GitHub (pinned to d6d39ce1c6)