{"record":{"id":"60841fe32b3f5f36","repo":"openclaw/openclaw","slug":"codex-session-is-not-a-non-archived-interactive-co-60841f","errorCode":null,"errorMessage":"Codex session is not a non-archived interactive Codex session","messagePattern":"Codex session is not a non-archived interactive Codex session","errorType":"validation","errorClass":"CatalogParamsError","httpStatus":null,"severity":"error","filePath":"extensions/codex/src/session-catalog-terminal.ts","lineNumber":91,"sourceCode":"    ? { canOpenTerminalCodex: true }\n    : {};\n}\n\nexport async function requireCatalogEligibleThread(\n  control: CodexSessionCatalogControl,\n  threadId: string,\n): Promise<CodexSessionCatalogSession> {\n  // Mutating actions use a fresh pinned control and authoritative thread/read. Passive positive hits\n  // may use the cadence-safe page memo; only a miss must bypass it before rejecting a new thread.\n  const cached = await findCatalogEligibleThread(control, threadId, false);\n  if (cached) {\n    return cached;\n  }\n  const refreshed = await findCatalogEligibleThread(control, threadId, true);\n  if (refreshed) {\n    return refreshed;\n  }\n  throw new CatalogParamsError(\"Codex session is not a non-archived interactive Codex session\");\n}\n\nasync function findCatalogEligibleThread(\n  control: CodexSessionCatalogControl,\n  threadId: string,\n  forceRefresh: boolean,\n): Promise<CodexSessionCatalogSession | undefined> {\n  let cursor: string | undefined;\n  const seenCursors = new Set<string>();\n  for (let pageIndex = 0; pageIndex < MAX_ACTION_CATALOG_PAGES; pageIndex += 1) {\n    const page = await control.listPage({\n      limit: CODEX_SESSION_CATALOG_MAX_PAGE_LIMIT,\n      ...(cursor ? { cursor } : {}),\n      ...(forceRefresh ? { forceRefresh: true } : {}),\n    });\n    const candidate = page.sessions.find((session) => session.threadId === threadId);\n    if (candidate) {\n      if (isInteractiveThreadSource(candidate.source)) {","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/openclaw/openclaw/blob/01804a75319da4b69c9ab98ceaa30477e22b8c0b/extensions/codex/src/session-catalog-terminal.ts#L73-L109","documentation":"Thrown by requireCatalogEligibleThread when neither the cached (cadence-safe) page scan nor the forced-refresh scan located the requested thread id among non-archived interactive Codex sessions. Mutating actions (continue/archive/terminal) require an authoritative eligibility confirmation before proceeding.","triggerScenarios":"Calling continue/archive/terminal resume with a threadId that does not exist on the app-server, is archived, belongs to a non-interactive source, or was deleted between catalog list and action.","commonSituations":"Stale threadId copied from an old catalog page; the session was archived by another client or CLI in the meantime; the thread is a non-interactive/internal Codex thread type.","solutions":["Refresh the Codex session catalog and re-pick the threadId from a current page.","Confirm the target is an interactive (non-archived) Codex session via `codex` CLI or app-server.","If the session was archived, restore or re-create it before retrying."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const fresh = await control.listPage({ limit: 100 });\nconst exists = fresh.sessions.some((s) => s.threadId === targetThreadId);\nif (!exists) {\n  // tell the user the session is gone and stop\n}","typeGuard":null,"tryCatchPattern":"try {\n  await requireCatalogEligibleThread(control, threadId);\n} catch (error) {\n  if (error instanceof CatalogParamsError && /not a non-archived interactive/.test(error.message)) {\n    // refresh catalog, reselect, or inform user the session is unavailable\n  }\n  throw error;\n}","preventionTips":["Always re-select the threadId from a freshly listed catalog page before a mutating action.","Treat a stale threadId as 'session no longer available' rather than retrying blindly."],"tags":["codex","session-catalog","validation","lifecycle"],"backgroundTag":null,"analyzedSha":"01804a75319da4b69c9ab98ceaa30477e22b8c0b","analyzedAt":"2026-08-12T04:37:58.197Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}