vercel/ai · warning

ACP connection closed before cancellation.

Error message

ACP connection closed before cancellation.

What it means

In the cancel path of runTurn, if the ACP connection object is already null (the agent connection closed), the bridge cannot send the session/cancel notification and throws this Error. The throw is caught immediately and recorded as cancellationFailureError, so it signals that cancellation could not be delivered to the agent rather than crashing the turn outright.

Source

Thrown at packages/harness-acp/src/v1/bridge/index.ts:238

    sessionId: activeSession.sessionId,
    model: start.model,
    mapping: start.modelMapping,
  });

  let rejectCancellationFailure!: (error: unknown) => void;
  const cancellationFailure = new Promise<never>((_, reject) => {
    rejectCancellationFailure = reject;
  });
  void cancellationFailure.catch(() => {});
  let cancellationRequested = false;
  let cancellationFailureError: Error | undefined;
  const cancel = async () => {
    if (cancellationRequested) return;
    cancellationRequested = true;
    activePermissionController?.cancelAll();
    try {
      if (connection == null) {
        throw new Error('ACP connection closed before cancellation.');
      }
      await connection.agent.notify(acp.methods.agent.session.cancel, {
        sessionId: activeSession.sessionId,
      });
    } catch (error) {
      cancellationFailureError = createACPBridgeError({
        stage: 'session cancellation',
        cause: error,
      });
      rejectCancellationFailure(cancellationFailureError);
    }
  };
  turn.emit({ type: 'stream-start' });
  const emitStreamEvent = createEmitStreamEvent({
    emit: event => turn.emit(event as BridgeEvent),
    emitToolCallCandidate: ({ toolCall }) => {
      turn.emit({
        type: 'acp-tool-call-candidate',

View on GitHub (pinned to 69428b1f8b)

Solutions

  1. Treat this as a benign race when the connection is already closed — the turn is over, so cancellation delivery is moot.
  2. Check agent stderr/logs to determine why the connection closed prematurely if cancellations routinely fail this way.
  3. Add application-level guard so cancellation is only requested while a turn is known to be active.
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await bridge.runTurn({ prompt, abortSignal });
} catch (error) {
  if (error instanceof Error && error.message === 'ACP connection closed before cancellation.') {
    // benign: agent already disconnected; inspect logs if it happens often
    return;
  }
  throw error;
}

Prevention

When it happens

Trigger: cancel() is invoked (e.g. by an abort signal or turn teardown) after the ACP agent process/connection has already terminated, so connection == null when attempting connection.agent.notify(acp.methods.agent.session.cancel, ...).

Common situations: User aborts the request at the same moment the agent process crashes or exits; the agent already finished/closed the connection before the abort signal fired; timeout logic cancels a turn whose connection already dropped.

Understand the failure class

Related errors


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/9b023214e9c1a110. Report an issue: GitHub.