paperclipai/paperclip · error

Capability live session is not connected

Error message

Capability live session is not connected

What it means

After attempting an automatic reconnect, sendMessage verifies the session has a live transport and a healthy status. If the transport is still null or the status is 'closed' or 'failed', the session cannot carry a turn, so it throws. This is the session-level 'not connected' guard.

Source

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

    attempt.failureCode = status === "failed"
      ? requireNonEmpty(failureCode ?? "attempt_failed", "attempt_failure_code")
      : null;
    await this.#persist();
    return this.snapshot();
  }

  async sendMessage(
    message: string,
    /** Launch-only diagnostics may opt out; qualification campaigns must not. */
    options: { allowMissingUsage?: boolean } = {},
  ): Promise<CapabilityLiveTurnResult> {
    const value = message.trim();
    if (value.length === 0) throw new Error("Capability live messages cannot be empty");
    if (this.#status === "suspended" || this.#transport === null) {
      await this.#connect(true);
    }
    if (this.#transport === null || this.#status === "closed" || this.#status === "failed") {
      throw new Error("Capability live session is not connected");
    }
    if (
      this.#activeTurnId !== null ||
      this.#turnWaiter !== null ||
      this.#pendingTurnAdmission !== null
    ) {
      throw new Error("Capability live session already has an active turn");
    }
    let settleAdmission!: () => void;
    const admission: PendingTurnAdmission = {
      transport: this.#transport,
      cancellation: null,
      settled: new Promise<void>((resolveSettled) => {
        settleAdmission = resolveSettled;
      }),
      settle: () => settleAdmission(),
    };
    this.#pendingTurnAdmission = admission;

View on GitHub (pinned to 01ad858492)

Solutions

  1. Recreate the session (or call the session's connect/resume path) and retry sendMessage
  2. Check session.status and transport presence before sending; handle closed/failed as terminal
  3. Inspect why #connect failed (process spawn error, auth, network) via the session's error/failure events
  4. Replace any cached session reference that was closed with a freshly constructed one

Example fix

// before
await session.sendMessage(msg); // session already closed
// after
if (session.status === 'closed' || session.status === 'failed') {
  session = await createLiveSession(opts);
}
await session.sendMessage(msg);
Defensive patterns

Strategy: try-catch

Validate before calling

if (session.status === 'closed' || session.status === 'failed' || session.transport === null) {
  throw new Error('session not live; reconnect first');
}

Type guard

function isLive(session: { status: string; transport: unknown }): boolean {
  return session.transport !== null && session.status !== 'closed' && session.status !== 'failed';
}

Try / catch

try {
  await session.sendMessage(msg);
} catch (e) {
  if ((e as Error).message === 'Capability live session is not connected') {
    await session.connect(); // or recreate session
    await session.sendMessage(msg);
  } else throw e;
}

Prevention

When it happens

Trigger: Calling sendMessage on a session whose transport dropped and whose #connect(true) reconnect failed; calling after the session was explicitly closed or entered 'failed' status (e.g. Codex process exited).

Common situations: Codex agent process crashed; network drop that reconnect could not recover; caller holds a stale session reference after close; suspended session whose resume also failed.

Understand the failure class

Background: ECONNREFUSED and "connection refused" / "could not connect to server" errors: what they mean and how to fix them — this error's family across 44 libraries.

Related errors


AI-assisted analysis of paperclipai/paperclip@01ad858492 (2026-09-10). Data as JSON: /api/errors/f0eff37ba11ccbac. Report an issue: GitHub.