Repository navigation
Description
What happened
I connected Codex through the new "Connect with ChatGPT" flow. Sign-in succeeded, but the provider showed "Could not check Codex right now. Retry, or reconnect in provider settings." Retrying and reconnecting didn't help. Turning on Windows Developer Mode and restarting T3 Code fixed it. After I turned Developer Mode off, it kept working until I updated the ChatGPT desktop app. Then the same error came back, and I had to turn Developer Mode on again.
Diagnosis
materializeCodexShadowHome links each entry of the shared Codex home (~/.codex) into the managed provider's shadow home through ensureSymlink (apps/server/src/provider/Drivers/CodexHomeLayout.ts:216). That function calls fileSystem.symlink(target, link) with no link type. On Windows, a normal (non-elevated) process can't create symbolic links unless Developer Mode is on, so every attempt fails with EPERM and the provider status check fails.
The failure keeps coming back because the list of entries is built from readDirectory(sharedHomePath) on every refresh (CodexHomeLayout.ts:361-378). That includes transient files the Codex/ChatGPT desktop app writes, such as ..codex-global-state.json.bak.tmp-<ts>-<uuid>. Each new temporary file needs a fresh link, so turning Developer Mode on only once isn't enough.
The codebase already works around this elsewhere. apps/server/src/provider/antigravityAuthSupport.ts:288 uses "junction" on win32 so it can link without elevation. Possible fixes:
- Use junctions for directories on win32.
- Use hard links or copies for files, since junctions only work for directories.
- Skip transient
*.tmp-*entries. - Treat a failure to link an unknown entry as non-fatal instead of failing the whole provider check.
Steps to reproduce
- On Windows 11 with Developer Mode off and a standard (non-admin) user, run the T3 Code desktop app.
- Go to Settings → Providers → Connect with ChatGPT, and finish the OpenAI sign-in.
- The provider shows "Could not check Codex right now." The server trace shows
CodexHomeLayout.ensureSymlinkfailing withEPERM. - Turn Developer Mode on and restart. The provider becomes ready.
- Turn Developer Mode off, then use or update the ChatGPT desktop app so it writes new temporary files in
~/.codex. The error comes back.
Version
0.0.44 (451afcb)
Environment
Windows 11 Home 10.0.26200 x64, desktop app with local server, Node v26.8.2, codex-cli 0.159.1
Evidence
CodexShadowHomeFileSystemError: Codex shadow home filesystem operation 'symlink' failed for '~\.t3\userdata\providers\codex\codex_<id>\shadow\sessions' to '~\.codex\sessions'.
at CodexHomeLayout.ensureSymlink (.../server/dist/bin.mjs:154178:10)
at materializeCodexShadowHome (.../server/dist/bin.mjs:154260:11)
at refreshSnapshot (.../server/dist/bin.mjs:127336:12)
[cause]: PlatformError: Unknown: FileSystem.symlink
[cause]: Error: EPERM: operation not permitted, symlink '~\.codex\sessions' -> '~\.t3\userdata\providers\codex\codex_<id>\shadow\sessions'
# After the ChatGPT desktop app update (Developer Mode off):
Failure ..codex-global-state.json.bak.tmp-1790718936714-<uuid> (x4)
# Before this, CodexChatGptAuth.authenticate -> SuccessRelated issues
#14321 is about the same ChatGPT connection, but it covers missing models, not this provider-check failure. Not a duplicate.
Fix applied or workaround
The user turned on Windows Developer Mode (Settings → System → For developers). It has to stay on, because new temporary files in ~/.codex need new symlinks.
Filed by
Claude Code (Claude Opus 5.5) via t3 triage
Activity
juliusmarminge commentedon Sep 29, 2026
Triage
Confirmed on
v0.0.44(451afcb). Nothing after that commit touches this path, and there is no open PR.Managed ChatGPT instances use an auth-overlay shadow home (
CodexManagedHome.ts: any instance id other thancodexgetsproviders/codex/<id>/shadow).materializeCodexShadowHomethen symlinks every non-private entry of~/.codexinto that directory, including the known directories it creates itself (sessions,sqlite,skills, and the rest).ensureSymlinkcalls Effect'sFileSystem.symlink, which has no Windows link-type argument and ends up asfs.symlinkwith no type. On Windows that is a real symlink, so a normal user without Developer Mode getsEPERM. The status check catches that and replaces it with "Could not check Codex right now," which matches the trace (sessions→refreshSnapshot). The built-in CLI provider (instanceId === "codex") stays in direct mode and does not hit this.Developer Mode only has to stay on because the entry list is rebuilt from
readDirectoryon every refresh. A new file such as..codex-global-state.json.bak.tmp-*is not inPRIVATE_ENTRY_NAMESorSHADOW_LOCAL_ENTRY_NAMES, so one unprivileged create fails the whole provider check. #14321 is the same sign-in flow, but it is the model catalog, not this.Junctions, as in
antigravityAuthSupport.ts, cover directories only, and they have to go throughnode:fsbecause Effect cannot pass"junction". Files still need a link, and a hard link or copy is not a symlink: the next refresh'sreadLinkreturnsEINVAL,readLinkStatetreats that asNotSymlink, andconfig.toml(anything outsidemcp-oauth-locks) fails withCodexShadowHomeEntryConflictError. Skipping transient*.tmp-*names, or not failing the check when an unknown entry cannot be linked, is still required for the recurrence.[-]Codex ChatGPT connection fails on Windows without Developer Mode: shadow home symlinks fail with EPERM[/-][+][BUG] Codex ChatGPT connection fails on Windows without Developer Mode: shadow home symlinks fail with EPERM[/+][-][BUG] Codex ChatGPT connection fails on Windows without Developer Mode: shadow home symlinks fail with EPERM[/-][+][Bug]: Codex ChatGPT connection fails on Windows without Developer Mode: shadow home symlinks fail with EPERM[/+]leonardoxr commentedon Oct 6, 2026
Still reproduces on 0.0.46-nightly.20261005.2702 (Windows 11 Pro 10.0.26200, standard non-elevated user, codex-cli 0.160.1). The "ChatGPT - Personal" managed instance showed "Authenticated as … · ChatGPT · Could not check Codex right now." The server trace had the same
CodexShadowHomeFileSystemError/EPERMon~\.codex\sessions(14 times), and theshadowdirectory stayed empty.Notes for anyone else hitting this:
ms-settings:developers). On this machine, turning the toggle on did not createHKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlockat all, and symlink creation still failed. Setting the value directly from an elevated shell worked:codexinstance (direct mode, uses the CLI's owncodex login) does not build a shadow home and works without symlink privileges.EPERM: operation not permitted, symlinkin~\.t3\userdata\logs\server.trace.ndjson.fix(server): Codex accounts in a shadow home start on Windows without…
fix(server): Codex shadow homes work on Windows when symlinks are ref…
fix(server): Codex shadow homes work on Windows when symlinks are ref…
lord007tn commentedon Oct 19, 2026
I did enable Developer Mode in Windows
and it's working properly
If anyone here wants a workaround
braziliansalsa commentedon Oct 21, 2026
Rechecked on 2026-10-26: still present in 0.1.2 (latest release), nightly
0.1.3-nightly.20261026.3717andmain(0712398). The link code is unchanged, and the regression tests in #22573 still fail againstmain.Following the close note on #15277, I opened a smaller fix: #22573. On Windows only, a directory falls back to a junction when Windows refuses the symlink, and an entry that cannot be linked is skipped instead of failing the check. It changes one source file plus tests. I verified it on Windows 11 with Developer Mode off, including Connect with ChatGPT and a thread running end to end; details are in the PR.
One trade-off needs a maintainer call: without Developer Mode, top-level files such as
config.tomlandAGENTS.mdare not shared into managed accounts.Written by Claude Code (Claude Opus 5.5) on behalf of @braziliansalsa, via t3 triage.
juliusmarminge commentedon Oct 22, 2026
Fresh triage: this is a reported Windows compatibility bug, not a reported exploitable vulnerability.
Inspected the server source on Linux at 07d38b8.
CodexHomeLayout.ensureSymlinkstill callsFileSystem.symlink(target, link)without a Windows link type;materializeCodexShadowHomestill rebuilds shared entries on refresh while keepingauth.jsonprivate. This is source inspection, not a Windows runtime reproduction: this host cannot run the reported Windows 11 desktop/Developer Mode sequence.Leaving this open for maintainer handling. Changing the managed account's credential-isolating shadow-home materialization falls under the triage flow's protected-surface stop. The existing proposed fix also needs a decision on which shared files remain available without Developer Mode.
ViperJuice commentedon Oct 29, 2026
Rechecked on 2026-10-29: this recurred on nightly
0.1.4-nightly.20261029.3853via PR #26286 ("Codex shadow homes share thread writer locks with the main home", merged 2026-10-28T04:58:30Z), which addedthread-writer-lockstoKNOWN_SHARED_DIRECTORIES— the sameensureSymlink→fileSystem.symlink(target, link)path this issue already tracks, with no Windows link-type argument.Environment: Windows 11 Pro 10.0.26300 x64, standard (non-admin) user, T3 desktop app, codex-cli 0.165.0-alpha.1.2 bundled runtime.
Observed error (T3 provider status UI):
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock\AllowDevelopmentWithoutDevLicensedid not exist at all on this machine (Developer Mode had never been turned on). Creating it and enabling Developer Mode unblocked a fresh symlink creation immediately (verified in a new session without any T3/app restart), confirming this is the same EPERM-without-privilege cause already diagnosed here.Additional evidence for the proposed junction-fallback fix (#22573): on this exact shadow home,
fsutil reparsepoint queryshows every pre-existing shared entry (cache,logs,mcp-oauth-locks,sessions, etc.) is a directory junction (IO_REPARSE_TAG_MOUNT_POINT), while the newthread-writer-lockslink that failed and was later created is a true NTFS symlink (IO_REPARSE_TAG_SYMLINK). A junction-on-Windows fallback for directory entries, as #22573 proposes, would have avoided this recurrence entirely.Workaround applied: enabled Windows Developer Mode; provider recovered.
grenmango51 commentedon Nov 6, 2026
Confirming the same recurrence on
0.1.8-nightly.20261106.4262(c55db3e9c7), Windows 11, standard non-admin user, Developer Mode never enabled.It is exactly the #26286 case, and nothing else.
shadow\thread-writer-locksis the only entry that needed a link. The ten pre-existing shared entries (archived_sessions,cache,logs,mcp-oauth-locks,plugins,sessions,shell_snapshots,skills,sqlite,worktrees) are all already junctions on this machine (fsutil reparsepoint query→ tag0xa0000003), so they never exercised the privilege. Only the newly addedthread-writer-lockswent through the real-symlink path, and it failed every refresh:182 failed
materializeCodexShadowHomespans in the retained trace, from14:27:30Zto16:14:54Z, roughly one a minute for the whole window. The provider showed as unavailable and sessions launched during it failed to start.The file is unchanged on
main.apps/server/src/provider/Drivers/CodexHomeLayout.tsatc55db3e9c7is byte-identical tomainat6577c6b6(sha256A946F1940EC378B8002A9DFA2365081ACC01601D8E244523CD90D36D4A23C41B):ensureSymlinkstill callsFileSystem.symlink(target, link)with no link type, andthread-writer-locksis still inKNOWN_SHARED_DIRECTORIES. This is live onmaintoday, not only in the nightlies that were reported.Repair, and what it says about #22573. Creating the missing link by hand recovered the provider on the next refresh:
materializeCodexShadowHomesucceeded at16:15:54Z, with no restart, and has succeeded 16 times since (latest16:31:45Z).fs.readlinkSyncreturns the absolute target T3 compares against, so a junction satisfiesreadLinkStateand the target comparison here. That means the directory half of #22573 is sufficient for this entry; the "skip unlinkable entries" half is not needed for it, though it is still needed for top-level files such asconfig.toml.One asymmetry worth knowing for the fix: older builds made the pre-existing entries as junctions, this build tried a true symlink for the new one, so a single shadow home can end up with both link kinds. Both pass the
readLinkcomparison — that is the state on disk here now, and nothing objects to it.The trigger is structural rather than a fluke, though: any future addition to
KNOWN_SHARED_DIRECTORIES, or any refresh that has to link an entry the shared home did not have before, fails on an unprivileged Windows account until someone with admin rights creates the link by hand.Written with an AI assistant (OpenCode) on behalf of @grenmango51.