openclaw/openclaw · error · Error

Claude session cannot be resumed in a terminal

Error message

Claude session cannot be resumed in a terminal

What it means

requireLocalResumableClaudeSession walks the local session catalog for a given threadId; it throws when the loop ends without returning — either the threadId was not found in any page, or it was found but isResumableClaudeSource(record.source) was false (that source type cannot be resumed in a terminal).

Source

Thrown at extensions/anthropic/session-catalog-node-commands.ts:53

    });
    const record = page.sessions.find((candidate) => candidate.threadId === threadId);
    if (record) {
      if (isResumableClaudeSource(record.source)) {
        return record;
      }
      break;
    }
    const nextCursor = page.nextCursor;
    if (nextCursor === undefined || seenCursors.has(nextCursor)) {
      break;
    }
    if (!isExactClaudeSessionCursor(nextCursor)) {
      throw new Error("Claude session catalog returned an invalid cursor");
    }
    seenCursors.add(nextCursor);
    cursor = nextCursor;
  }
  throw new Error("Claude session cannot be resumed in a terminal");
}

export async function listClaudeSessions(paramsJSON?: string | null): Promise<string> {
  return JSON.stringify(await listLocalClaudeSessionPage(parseNodeParams(paramsJSON)));
}

export async function readClaudeSession(paramsJSON?: string | null): Promise<string> {
  return JSON.stringify(await readLocalClaudeTranscriptPage(parseNodeParams(paramsJSON)));
}

export async function resumeClaudeSession(
  paramsJSON: string | null | undefined,
  io: OpenClawPluginNodeHostCommandIo | undefined,
): Promise<string> {
  if (!io) {
    throw new Error("Claude terminal command requires duplex transport");
  }
  const params = decodeNodePtyResumeParams(paramsJSON, validateClaudeSessionId);

View on GitHub (pinned to 01804a7531)

Solutions

  1. List local sessions (listClaudeSessions) and confirm the threadId exists on this host.
  2. Verify the session's source is one isResumableClaudeSource accepts — only resumable sources can be terminal-resumed.
  3. If the session is remote, resume it through its native surface instead of the terminal path.
  4. Rebuild the local session catalog if the index is stale or empty.

Example fix

// before
const record = await requireLocalResumableClaudeSession(params.threadId); // throws
// after — check existence and resumability explicitly for a precise message
const record = await findLocalSession(params.threadId);
if (!record) throw new Error(`Session ${params.threadId} not found locally`);
if (!isResumableClaudeSource(record.source))
  throw new Error(`Session ${params.threadId} source (${record.source}) is not terminal-resumable`);
Defensive patterns

Strategy: validation

Validate before calling

// Confirm the session exists and is resumable before attempting terminal resume.
const page = await listLocalClaudeSessionPage({ limit: 100 });
const record = page.sessions.find(s => s.threadId === threadId);
if (!record || !isResumableClaudeSource(record.source)) { /* not terminal-resumable */ }

Type guard

import { isResumableClaudeSource } from './session-catalog-shared.js';
// isResumableClaudeSource(record.source): boolean — narrows to terminal-resumable sources

Try / catch

try { await requireLocalResumableClaudeSession(threadId); } catch (e) {
  if (/cannot be resumed/.test(String(e.message))) { /* list sessions; suggest native resume */ }
}

Prevention

When it happens

Trigger: (a) threadId matches no local session across all catalog pages; (b) the matching session's source type is not resumable in a terminal (e.g. a remote/non-PTY source); (c) pagination ended early because nextCursor was undefined or repeated.

Common situations: Resuming a session that lives on a different host; a threadId typo or stale id; the session exists only in a source the terminal resumer does not support; a local session index not yet populated.

Related errors


AI-assisted analysis of openclaw/openclaw@01804a7531 (2026-08-12). Data as JSON: /api/errors/275fddd7ce6baa8e. Report an issue: GitHub.