Skip to content

fix: normalize Windows extended-length paths in import ledger lookup (#513)#551

Open
AndrewAvery7 wants to merge 1 commit into
openai:mainfrom
AndrewAvery7:fix-513-windows-ledger-path
Open

fix: normalize Windows extended-length paths in import ledger lookup (#513)#551
AndrewAvery7 wants to merge 1 commit into
openai:mainfrom
AndrewAvery7:fix-513-windows-ledger-path

Conversation

@AndrewAvery7

@AndrewAvery7 AndrewAvery7 commented Jul 24, 2026

Copy link
Copy Markdown

Problem

On Windows, /codex:transfer always reports:

Codex reported that the Claude import completed, but did not record an imported thread.

even though the thread is actually created (#513; likely also the root cause behind #417 / #514 reports on Windows).

Root cause

importedThreadIdForSource() in plugins/codex/scripts/lib/codex.mjs compares the ledger's source_path against fs.realpathSync(sourcePath) with strict string equality. On Windows, Codex writes ledger records with the extended-length path prefix:

{ "source_path": "\\?\C:\Users\<user>\.claude\projects\...\session.jsonl", ... }

while realpathSync returns the plain form (C:\Users\<user>\...). The two never compare equal, so the lookup returns null and the command reports a false failure.

Fix

Add normalizeLedgerPath(): strip the extended-length prefix (both the drive form \\?\C:\... and the network form \\?\UNC\server\share\...) from both sides of the comparison, and compare case-insensitively on win32. Non-Windows behavior is unchanged (identity comparison, exactly as before).

Testing

  • Verified against a real Windows 11 ledger produced by Codex CLI 0.145.0: records carry the extended-length prefix exactly as described, and the normalized comparison matches where the strict one fails.
  • Unit-tested the normalizer: prefixed-vs-plain match, case-insensitive match, UNC-prefixed vs plain UNC match, non-matching paths still rejected, plain-vs-plain unchanged (5/5 pass).
  • node --check passes on the modified module.
  • The same normalization logic has been running in production in a wrapper tool (claude-codex-bridge) that detects imported threads out-of-band; it resolved the false failures across many real transfers, including 6 MB sessions.

Fixes #513

🤖 Generated with Claude Code

importedThreadIdForSource compared fs.realpathSync output against ledger
source_path records with strict equality. On Windows, Codex writes ledger
paths with the \?\ extended-length prefix while realpathSync returns the
plain form, so the comparison never matched: every successful transfer was
reported as 'did not record an imported thread' (openai#513).

Normalize both sides before comparing: strip \?\ (and \?\UNC\), and
compare case-insensitively on win32.

Fixes openai#513

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/codex:transfer always reports "did not record an imported thread" on Windows (thread is actually created)

1 participant