oracle/graal · error · ContinuationExecutionException

An exception escaped the continuation.

Error message

An exception escaped the continuation.

What it means

This is the message of ContinuationExecutionException, thrown by ContinuationImpl's run entry (startInternal) when entryPoint.start(cap) throws. The library wraps the escaping throwable so callers can distinguish 'the code inside the continuation failed' from 'the continuation machinery failed'; the original exception is the cause. The continuation is also transitioned to State.FAILED before rethrowing.

Source

Thrown at espresso/src/org.graalvm.continuations/src/org/graalvm/continuations/ContinuationImpl.java:708

     */
    @SuppressWarnings("unused")
    private void run() {
        assert state == State.RUNNING : state; // set in #resume()
        SuspendCapability cap = SuspendCapability.create(this);
        try {
            try {
                entryPoint.start(cap);
            } catch (Throwable e) {
                if (!updateState(State.RUNNING, State.FAILED)) {
                    // force failed state and maybe assert
                    State badState = forceState(State.FAILED);
                    if (ASSERTIONS_ENABLED) {
                        AssertionError assertionError = new AssertionError(badState.toString());
                        assertionError.addSuppressed(e);
                        throw assertionError;
                    }
                }
                throw new ContinuationExecutionException(e);
            }
            if (!updateState(State.RUNNING, State.COMPLETED)) {
                // force completed state and maybe assert
                State badState = forceState(State.COMPLETED);
                if (ASSERTIONS_ENABLED) {
                    throw new AssertionError(badState.toString());
                }
            }
        } finally {
            stackFrameHead = null;
        }
    }

    /**
     * A newly constructed continuation starts in {@link State#NEW}. After the first call to
     * {@link #resume()} the state will become {@link State#RUNNING} until either the entry point
     * returns, at which point the state becomes {@link State#COMPLETED}, or until the continuation
     * suspends, at which point it will be {@link State#SUSPENDED}.

View on GitHub (pinned to a66e9ccd1d)

Solutions

  1. Inspect getCause() of the ContinuationExecutionException — the root cause is always the exception that escaped the entry point; fix that first.
  2. Wrap the body of your ContinuationEntryPoint.start in a try-catch that records the failure, so the continuation completes or fails on its own terms.
  3. Catch ContinuationExecutionException at the call site of Continuation.start to convert it into your application's error type instead of letting it propagate.
  4. Check getState() after the failure — the continuation is FAILED and must be rebuilt, not resumed.

Example fix

// before
class Task implements ContinuationEntryPoint {
    public void start(SuspendCapability cap) {
        doWork(); // throws, escapes as ContinuationExecutionException
    }
}

// after
class Task implements ContinuationEntryPoint {
    public void start(SuspendCapability cap) {
        try {
            doWork();
        } catch (Exception e) {
            failure = e; // handle inside; nothing escapes
        }
    }
}
Defensive patterns

Strategy: try-catch

Try / catch

try { cont.start(entry); } catch (ContinuationExecutionException e) { Throwable root = e.getCause(); /* log root, rebuild continuation: state is FAILED */ }

Prevention

When it happens

Trigger: The ContinuationEntryPoint.start implementation (or anything it calls on the continuation's stack) throws any Throwable while the continuation runs via Continuation.start/enter; the guest code has an unhandled exception at its top frame.

Common situations: Business logic inside the continuation throwing a RuntimeException or Error; a suspend-capable task whose entry point does not catch its own exceptions; NPEs or timeouts surfacing from guest code during a resumed continuation.

Related errors


AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14). Data as JSON: /api/errors/1cf90bc5bb806104. Report an issue: GitHub.