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

  1. Inspect the appended stderr (cleanCodexStderr output) included in the message for the underlying import error.
  2. Check the Codex app-server logs in the session dir for the import failure detail.
  3. Retry after upgrading Codex to a version known to write the import ledger reliably.
  4. 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.
  5. 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

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


AI-assisted analysis of openai/codex-plugin-cc@db52e28f4d (2026-08-13). Data as JSON: /api/errors/757c7f268b51d8f3. Report an issue: GitHub.