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
- Pass an explicit --project/--conversation/--index/--thread-id that matches a visible sidebar row
- Keep the target conversation visible/open in the Codex sidebar before running the action
- Run `opencli codex projects` (or list) to see what the library currently resolves
- 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
- Always pass an explicit --thread-id in scripts instead of relying on the active conversation
- List current conversations before acting to confirm the target exists
- Wait for sidebar refresh after navigation before resolving
- Handle archived/renamed conversations by re-listing ids
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
- Could not switch to ${wantModel} model
- Claude composer is not available on the current page.
- Codex sidebar extraction returned an invalid payload.
- Failed to perform action.
- ${pickerResult?.reason || 'Failed to open Gemini model picke
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b9b21e21ecc82ec7.
Report an issue: GitHub.