jackwener/OpenCLI · error · CommandExecutionError

Could not resolve a stable Codex conversation identity.

Error message

Could not resolve a stable Codex conversation identity.

What it means

After (optionally) opening a conversation, resolveActionConversation matches the selected row against the extracted sidebar projects. If no project/conversation matches the requested --project/--conversation/--index/--thread-id (or no active conversation is visible), it throws this CommandExecutionError with a hint about how to disambiguate.

Source

Thrown at clis/codex/_actions.js:101

export async function readConversationProjects(page) {
    const projects = unwrapEvaluateResult(await page.evaluate(`(${collectCodexProjectsFromDocument.toString()})()`));
    if (!Array.isArray(projects)) {
        throw new CommandExecutionError('Codex sidebar extraction returned an invalid payload.');
    }
    return projects;
}

export async function resolveActionConversation(page, kwargs) {
    const selected = await openCodexConversation(page, kwargs);
    const projects = await readConversationProjects(page);
    const resolved = selected
        ? findCodexConversation(projects, selected)
        : findActiveCodexConversation(projects);
    if (!resolved) {
        const hint = hasConversationTarget(kwargs)
            ? 'The selected Codex conversation was not visible after selection.'
            : 'Pass --project/--conversation/--index/--thread-id, or keep the active conversation visible in the sidebar.';
        throw new CommandExecutionError('Could not resolve a stable Codex conversation identity.', hint);
    }
    if (!resolved.conversation.threadId) {
        throw new CommandExecutionError(
            'Could not resolve a stable Codex conversation identity.',
            'The selected sidebar row is missing its Codex thread id; selectors may have drifted.',
        );
    }
    return {
        project: resolved.project.project,
        projectPath: resolved.project.projectPath,
        conversation: resolved.conversation.title,
        threadId: resolved.conversation.threadId,
        pinned: resolved.conversation.pinned,
        index: resolved.conversation.index,
    };
}

function conversationRefForError(ref) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass an explicit --project/--conversation/--index/--thread-id that matches a visible sidebar row
  2. Keep the target conversation visible/open in the Codex sidebar before running the action
  3. Run `opencli codex projects` (or list) to see what the library currently resolves
  4. Re-run after the sidebar finishes refreshing

Example fix

// before
await action(page, {}); // relies on active conversation
// after
await action(page, { threadId: 'abc-123' }); // explicit target
Defensive patterns

Strategy: try-catch

Validate before calling

const projects = await readConversationProjects(page);
const visible = projects.flatMap(p => p.conversations);
if (kwargs.threadId && !visible.some(c => c.threadId === kwargs.threadId)) {
  throw new Error(`Conversation ${kwargs.threadId} not visible in sidebar`);
}

Type guard

function hasConversationTarget(kwargs) {
  return Boolean(kwargs && (kwargs.project || kwargs.conversation || kwargs.index != null || kwargs.threadId));
}

Try / catch

try {
  await action(page, kwargs);
} catch (e) {
  if (e instanceof CommandExecutionError && e.message.includes('stable Codex conversation identity')) {
    console.error(e.hint || 'Pass --project/--conversation/--index/--thread-id');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling a Codex action whose target conversation is not present in the sidebar after selection: wrong --thread-id, index out of range, conversation archived/renamed, or the sidebar did not refresh after clicking the target.

Common situations: Stale thread ids from old sessions, conversations not visible because another project filter is active, slow sidebar updates after programmatic navigation.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/b9b21e21ecc82ec7. Report an issue: GitHub.