flowable/flowable-engine · error · PvmException

couldn't process signal

Error message

couldn't process signal '${signalName}' on activity '${activityId}': 

What it means

Thrown when a SignallableActivityBehavior.signal(execution, signalName, signalData) throws a checked Exception while the execution is being signalled (e.g. resuming a wait state). The PVM wraps it in a PvmException with the signal name and activity id. Runtime exceptions are rethrown as-is.

Solutions

  1. Inspect the cause of the PvmException to identify the failing behavior
  2. Fix the checked-exception path inside the activity's signal() implementation
  3. Catch/wrap checked exceptions in the behavior before they reach the engine
  4. Verify the executionId being signalled corresponds to the expected wait state

Example fix

// before
public void signal(DelegateExecution exec, String signalName, Object data) throws Exception {
  queue.send(signalName, data); // throws checked Exception
}
// after
public void signal(DelegateExecution exec, String signalName, Object data) {
  try { queue.send(signalName, data); }
  catch (Exception e) { throw new ActivitiException("signal delivery failed", e); }
}
Defensive patterns

Strategy: try-catch

Validate before calling

// confirm execution is actually waiting before signalling
Execution e = runtimeService.createExecutionQuery().executionId(id).singleResult();
if (e == null) throw new IllegalArgumentException("execution not found: " + id);

Type guard

if (activityBehavior instanceof SignallableActivityBehavior) { ... }

Try / catch

try {
  runtimeService.signal(executionId, signalName, data);
} catch (PvmException e) {
  log.error("signal {} failed", signalName, e.getCause());
}

Prevention

When it happens

Trigger: runtimeService.signal(executionId) or signal variants reaching a wait-state activity (receive task, user task gateway) whose SignallableActivityBehavior.signal() throws a checked exception; also custom signallable behaviors with checked failure paths.

Common situations: Signalling an execution whose underlying behavior touches external systems; custom wait-state implementations throwing checked IO exceptions; signalling the wrong execution id so the resolved activity's signal logic fails.

Related errors


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

Appendix: source

Thrown at modules/flowable5-engine/src/main/java/org/activiti/engine/impl/pvm/runtime/ExecutionImpl.java:574

    public void start() {
        if (startingExecution == null && isProcessInstanceType()) {
            startingExecution = new StartingExecution(processDefinition.getInitial());
        }
        performOperation(AtomicOperation.PROCESS_START);
    }

    // methods that translate to operations /////////////////////////////////////

    @Override
    public void signal(String signalName, Object signalData) {
        ensureActivityInitialized();
        SignallableActivityBehavior activityBehavior = (SignallableActivityBehavior) activity.getActivityBehavior();
        try {
            activityBehavior.signal(this, signalName, signalData);
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            throw new PvmException("couldn't process signal '" + signalName + "' on activity '" + activity.getId() + "': " + e.getMessage(), e);
        }
    }

    @Override
    public void take(PvmTransition transition, boolean fireActivityCompletedEvent) {
        // No event firing on executionlevel impl
        take(transition);
    }

    @Override
    public void take(PvmTransition transition) {
        if (this.transition != null) {
            throw new PvmException("already taking a transition");
        }
        if (transition == null) {
            throw new PvmException("transition is null");
        }
        setTransition((TransitionImpl) transition);

View on GitHub (pinned to d6d39ce1c6)