openai/codex-plugin-cc · error · Error
Codex reported that the Claude import completed, but did not
Error message
Codex reported that the Claude import completed, but did not record an imported thread.${stderr ? `\n${stderr}` : " Check the Codex app-server logs for the underlying import error."} What it means
Thrown by importExternalAgentSession when the import RPC reported completion (the EXTERNAL_AGENT_IMPORT_COMPLETED notification fired) but importedThreadIdForSource(sourcePath) returned null. That helper reads ~/.codex/external_agent_session_imports.json and matches a record by realpath + content sha256 + imported_thread_id; no match means the app-server acknowledged completion but did not (or not yet) persist a usable thread id.
Source
Thrown at plugins/codex/scripts/lib/codex.mjs:1083
}
return withDirectAppServer(cwd, async (client) => {
emitProgress(options.onProgress, "Importing Claude session into Codex.", "transferring");
try {
await requestExternalAgentSessionImport(client, externalAgentSessionMigration(options.sourcePath, cwd));
} catch (error) {
if (error?.rpcCode === -32601) {
throw new Error(
"This Codex version does not support Claude session transfer. Update Codex with `npm install -g @openai/codex@latest`, then retry.",
{ cause: error }
);
}
throw error;
}
const threadId = importedThreadIdForSource(options.sourcePath);
if (!threadId) {
const stderr = cleanCodexStderr(client.stderr);
throw new Error(
`Codex reported that the Claude import completed, but did not record an imported thread.${stderr ? `\n${stderr}` : " Check the Codex app-server logs for the underlying import error."}`
);
}
emitProgress(options.onProgress, `Claude session imported (${threadId}).`, "completed", { threadId });
return {
threadId,
stderr: cleanCodexStderr(client.stderr)
};
});
}
export async function runAppServerTurn(cwd, options = {}) {
const availability = getCodexAvailability(cwd);
if (!availability.available) {
throw new Error("Codex CLI is not installed or is missing required runtime support. Install it with `npm install -g @openai/codex`, then rerun `/codex:setup`.");
}
return withAppServer(cwd, async (client) => {View on GitHub (pinned to db52e28f4d)
Solutions
- Inspect the appended stderr (cleanCodexStderr output) included in the message for the underlying import error.
- Check the Codex app-server logs in the session dir for the import failure detail.
- Retry after upgrading Codex to a version known to write the import ledger reliably.
- Verify read permission on ~/.codex/external_agent_session_imports.json and that its records array contains an entry matching the source path and content hash.
- If the transcript was modified mid-import, re-run with a stable source file.
Example fix
// before
await importExternalAgentSession(cwd, { sourcePath }) // throws: no recorded imported thread
// after (diagnostic)
// cat ~/.codex/external_agent_session_imports.json # check records
// inspect session-dir app-server logs for import error
// npm install -g @openai/codex@latest # then retry
await importExternalAgentSession(cwd, { sourcePath }) Defensive patterns
Strategy: try-catch
Validate before calling
import fs from 'node:fs';
import path from 'node:path';
function findImportedThreadId(sourcePath, codexHome) {
const ledgerPath = path.join(codexHome, 'external_agent_session_imports.json');
if (!fs.existsSync(ledgerPath)) return null;
const ledger = JSON.parse(fs.readFileSync(ledgerPath, 'utf8'));
const canonical = fs.realpathSync(sourcePath);
// caller can pre-check whether a matching record exists
return (ledger.records ?? []).some(r => r.source_path === canonical) ?? false;
} Type guard
null
Try / catch
try {
await importExternalAgentSession(cwd, { sourcePath });
} catch (error) {
if (/did not record an imported thread/.test(error.message)) {
// read ~/.codex/external_agent_session_imports.json and app-server logs,
// surface stderr captured in error.message, then retry or report
} else throw error;
} Prevention
- Treat the appended stderr in the message as the primary diagnostic.
- Ensure ~/.codex is writable by the app-server process.
- Avoid modifying the transcript while an import is in flight (sha256 must stay stable).
- Upgrade Codex if the ledger write is unreliable in your installed version.
When it happens
Trigger: The 'externalAgentConfig/import' notification arrives, but the ledger file is absent, has no records array, or none of the records match the canonical source path and content hash. Also possible if the app-server logged an internal import error to stderr instead of writing the ledger.
Common situations: Codex app-server bug or partial failure where the session is created internally but the ledger write is skipped. File content changed between the realpath/sha256 computation and ledger matching (race). Permissions prevent writing ~/.codex/external_agent_session_imports.json. An app-server version mismatch in the ledger schema.
Related errors
- A Claude session source path is required.
- This Codex version does not support Claude session transfer.
- Job ${active.id} is still ${active.status}. Check /codex:sta
- Codex CLI is not installed or is missing required runtime su
- Task ${activeTask.id} is still running. Use /codex:status be
AI-assisted analysis of openai/codex-plugin-cc@db52e28f4d (2026-08-13).
Data as JSON: /api/errors/757c7f268b51d8f3.
Report an issue: GitHub.