paperclipai/paperclip · error

Capability live turn admission was abandoned during teardown

Error message

Capability live turn admission was abandoned during teardown

What it means

During sendMessage turn admission, the session checks that the pending admission object is still the session's current one (#pendingTurnAdmission === admission). If a concurrent teardown (close/fail/interrupt) already released or replaced the admission, the in-flight start can no longer proceed and throws instead of writing into a torn-down session.

Source

Thrown at packages/paperclip-runner/src/live/live-session.ts:1523

          await admission.transport.attachRun(binding);
          this.#providerRunBinding = binding;
          await this.#persist();
        } catch (error) {
          admissionFailure = error;
        }
      }
      // A transport without cross-run attachment keeps subsequent provider
      // turns inside this capability session's existing governed run. This is
      // distinct from reusing the provider under a different PRP authority.
    }
    let workspaceBefore: PaperclipWorkspaceSnapshot | null = null;
    try {
      workspaceBefore = await workspaceBeforePromise;
    } catch (error) {
      admissionFailure ??= error;
    }
    if (this.#pendingTurnAdmission !== admission) {
      throw new Error("Capability live turn admission was abandoned during teardown");
    }
    if (admissionFailure !== null) {
      return this.#failTurnAdmission(admission, userEntryId, admissionFailure);
    }
    if (admission.cancellation !== null) {
      return this.#completeInterruptedAdmission(admission, userEntryId);
    }
    if (workspaceBefore === null) {
      this.#appendEvidence("diagnostic", null, {
        code: "workspace_baseline_deadline_exceeded",
        message:
          "The runner could not establish an exact pre-turn workspace baseline inside its bounded admission window; workspace diff projection is unavailable for this turn.",
      });
    }
    if (
      this.#pendingTurnAdmission !== admission ||
      this.#transport !== admission.transport ||
      this.#status !== "running"

View on GitHub (pinned to 01ad858492)

Solutions

  1. Ensure session teardown does not run while sendMessage is in flight (serialize lifecycle and turn calls)
  2. Catch this error in the sendMessage caller and treat it as 'turn did not start' — do not retry on the same (torn-down) session
  3. Re-check session status before sending; avoid firing sends after calling close/fail
  4. If teardown is intentional, surface this as an expected cancellation rather than a bug

Example fix

// before
const sendPromise = session.sendMessage(msg);
session.close(); // teardown races admission
await sendPromise; // throws 'abandoned during teardown'
// after
await session.sendMessage(msg);
await session.close();
Defensive patterns

Strategy: try-catch

Validate before calling

if (session.status === 'closed' || session.status === 'failed') throw new Error('session tearing down; not sending');

Type guard

null

Try / catch

try {
  await session.sendMessage(msg);
} catch (e) {
  if ((e as Error).message === 'Capability live turn admission was abandoned during teardown') {
    // turn never started; do not retry on this session
  } else throw e;
}

Prevention

When it happens

Trigger: Session close/fail/teardown runs while sendMessage is awaiting the workspaceBefore promise (pre-turn workspace snapshot); admission released between start of admission and the equality check.

Common situations: A supervisor closes the session concurrently with a user sending a message; a timeout path tears down the session while a turn is starting; error in another awaited step triggered session teardown mid-admission.

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 paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/124a5257c99fc0ac. Report an issue: GitHub.