VS Code Codex diff fails to load full file content
What version of the IDE extension are you using?
26.513.21555
What subscription do you have?
Plus
Which IDE are you using?
VS Code
What platform is your computer?
Darwin 25.4.0 arm64 arm (Mac OS)
What issue are you seeing?
In the VS Code Codex diff view, a simple change to a tracked file fails to load the full file content.
The UI shows:
Full file content failed to load
with a Retry button. Clicking Retry does not resolve the issue.
What steps can reproduce the bug?
Feedback ID: 019e45e7-3599-7a50-b966-f908ecaebd35
- Open a git repository in VS Code with the Codex extension enabled.
- Ask the Codex extension to modify a tracked file. In my repro, the file was
robots.txt. - Codex made a simple one-line insertion:
``diff``
# https://www.robotstxt.org/robotstxt.html
+# Site crawler access rules
User-agent: *
Disallow:
- Open the Codex diff view for that change by clicking the review button in the chat.
- Observe that the diff view shows the file header, the full-content load failure, and only a few diff lines:
``text``
robots.txt
Full file content failed to load
<a few diff lines>
- Click the
Retrybutton. - The same failure remains.
What is the expected behavior?
_No response_
Additional information
Diagnostic Notes From Local Instrumentation
The following section is based on local instrumentation added by Codex itself while debugging. Please treat it as reference material, not as a definitive fix proposal.
After adding temporary logging to the local installed extension bundle, the failing full-content load appeared to come from the diff webview calling:
git.request({
method: "cat-file",
params: {
cwd,
path,
oid,
fallbackToDisk,
operationSource: "thread_diff"
}
})
The debug output showed that the diff metadata used an absolute path:
diff.name: /private/tmp/codex-review-repro/robots.txt
workspaceRoot: /private/tmp/codex-review-repro
But the cat-file request appeared to expect a repository-relative path:
robots.txt
With the absolute path, both sides initially failed:
{
oldResult: {
type: "error",
error: { type: "not-found" }
},
newResult: {
type: "error",
error: { type: "not-found" }
}
}
After locally normalizing the path from:
/private/tmp/codex-review-repro/robots.txt
to:
robots.txt
the new side loaded successfully from disk, but the old side still failed:
{
oldResult: {
type: "error",
error: { type: "not-found" }
},
newResult: {
type: "success",
lines: [
"# https://www.robotstxt.org/robotstxt.html\n",
"# Site crawler access rules\n",
"User-agent: *\n",
"Disallow:\n"
]
},
nextFallbackToDisk: false
}
The old side appeared to fail because the diff metadata did not include prevObjectId, and the request effectively had:
oid: null
fallbackToDisk: false
The extension-side cat-file handler appears to return not-found for that combination.
As a local experiment only, I patched the installed extension to resolve the old side with:
git rev-parse HEAD:<path>
and then read that blob with git cat-file. With that local experiment, the full-content load succeeded and the Retry button disappeared.
Possible Cause
Based on the above local investigation, the failure may involve two related issues:
- The partial diff metadata may provide an absolute file path where the full-content loader expects a repo-relative path.
- The old-side full-content loader may not have a fallback when
prevObjectIdis missing andfallbackToDiskis false.
Again, this diagnosis was produced from local instrumentation and should be treated as a debugging lead rather than a confirmed root cause.
8 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Undo and reapply seems to be working on my side.
And this issue only happens in the VS Code extension. The same conversation, when opened in the Mac OS Codex app, is working correctly without that issue.
I encountered the same problem on win11.
I also encountered the same problem in the Codex application of Windows 11. The issue doesn't occur when I disable the "Load Complete File" option. Could it be because the context of the complete file is too lengthy?
I hit what looks like the same underlying bug in Codex Desktop, with a worktree/cwd mismatch variant.
Environment:
cli_version: 0.133.0Full file content failed to load, with a retry button.Anonymized repro shape:
The patch/diff itself rendered correctly because the
patch_apply_endevent had the absolute changed-file path and unified diff. However, when the diff viewer tried to expand/load the full file content for the changed file, it showed the full-content load failure.In this case the target file still existed on disk and was readable after the failure:
So this does not look like a missing-file or permission issue. It looks consistent with the diagnosis above: the diff metadata/full-content loader does not consistently handle absolute paths, or it resolves/validates the file against the thread cwd/workspace root instead of the actual worktree path recorded in the patch event.
Expected behavior:
fs/readFile/cat-fileinstead of only showing the generic full-content failure message.This seems related to #23709 rather than a separate issue, so adding it here as another data point.
I have the same with my VS Code (running on Windows 11). I see for every changed file this message:
<img width="508" height="285" alt="Image" src="https://github.com/user-attachments/assets/8b6b555a-d5ca-4234-af25-fa2628701af8" />
I reproduced this on Windows Desktop and found a second, deterministic failure mode that is independent of file size or encoding.
Environment
26.616.81150git status,git cat-file, and object checks all behaved normally)Root cause observed
The turn diff contains blob-looking object IDs that are calculated from the captured before/after contents, but those blobs are not necessarily present in the repository object database.
Current
TurnDiffTracker::render_diff()computes both IDs withgit_blob_oid(...)and writes them into the unified diff'sindexline:https://github.com/openai/codex/blob/a0d5fd772e076851e6f17d1e821c797154e2916f/codex-rs/core/src/turn_diff_tracker.rs#L309-L355
The desktop full-content loader then interprets those IDs as resolvable Git objects and requests
git cat-filewithoperationSource: "thread_diff". For newly generated, uncommitted content, the computed SHA-1 identifies what the blob would be, butTurnDiffTrackerhas not written that blob into Git's object database.I verified the sequence directly in the affected repository:
git hash-object <file>.git cat-file -e <computed-id>^{blob}exits128because the object is absent.Full file content failed to load.git cat-file -enow exits0.This explains the persistent Retry behavior and why the problem can affect small, valid files. It also complements the absolute-path/worktree observations already reported here: path normalization can be correct and the lookup can still fail because a synthesized object ID is not an ODB-backed object.
Suggested invariant
A blob ID emitted in turn-diff metadata should only be used for
cat-filewhen its provenance guarantees that it is readable from the target repository. Captured-content hashes and repository object IDs are currently indistinguishable to the client.Potential fixes, in preference order:
not-found.cat-filework, but seems less desirable because it mutates the repository object store and leaves unreachable blobs.For the old side, falling back to
HEAD:<path>is not fully correct because the patch baseline may itself contain uncommitted edits. The captured baseline held byTurnDiffTrackeris the authoritative source.Regression coverage I would propose
HEAD.cat-filelookup.I can prepare the focused test and implementation if this direction matches the intended desktop/app-server architecture. Since external PRs require an explicit maintainer invitation, please let me know whether you would prefer an app-server snapshot lookup or another approach.
I reproduced this on current Codex Desktop for macOS, and the failure still occurs in an aggregate-root + nested-worktree layout.
Environment
26.707.31428(build5059)0.144.0-alpha.4Anonymized layout:
Observed behavior
The partial hunk renders, but expanding it shows:
The file still exists and is normally readable. The Git baseline can also be read when the correct worktree root is used:
The equivalent lookup from the thread/aggregate cwd fails:
A useful additional detail: the affected Codex turn did not modify any files. The Review sidebar discovered pre-existing dirty files from the nested worktree. This means diff discovery can identify a nested worktree under an aggregate project, while the full-content loader still appears to retain the thread cwd instead of the owning repository/worktree root.
Expected behavior
For each discovered diff, full-content loading should carry the owning Git repository/worktree root and use a repository-relative path for the before/index side. Retry should not repeat a lookup from a known non-Git aggregate cwd.
Disabling “Load full files” remains a workaround, but the full context should load correctly for nested repositories/worktrees.