codex - 💡(How to fix) Fix Desktop app: side chat fails with "failed to read thread /Users/<me>/.codex: Is a directory (os error 21)" after idle

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

After leaving the Codex desktop app's side chat idle for a while, the next attempt to send a message fails with a toast error:

创建任务时出错 (Error creating task) failed to read thread: thread-store internal error: failed to read thread /Users/<me>/.codex: Is a directory (os error 21)

The path the thread store tries to open is the ~/.codex directory itself, not a rollout-*.jsonl file under ~/.codex/sessions/..., which is why the OS returns EISDIR (21). It looks like the in-memory reference to the active thread gets cleared/invalidated while the side chat panel is idle, and on the next request the code path joins an empty thread identifier onto the codex home directory and tries to read the result as a file.

Error Message

Happy to attach ~/.codex/log/ excerpts if useful — let me know what range / log file you'd like.

Root Cause

Guess at root cause

Fix Action

Fix / Workaround

Hard error toast; the only workaround is to click "New chat" / reload the window / restart the app.

Workarounds that fix it

RAW_BUFFERClick to expand / collapse

What version of the Codex App are you using (From “About Codex” dialog)?

26.513.20950 (2816)

What subscription do you have?

Plus

What platform is your computer?

Darwin 25.4.0 arm64 arm

What issue are you seeing?

Summary

After leaving the Codex desktop app's side chat idle for a while, the next attempt to send a message fails with a toast error:

创建任务时出错 (Error creating task) failed to read thread: thread-store internal error: failed to read thread /Users/<me>/.codex: Is a directory (os error 21)

The path the thread store tries to open is the ~/.codex directory itself, not a rollout-*.jsonl file under ~/.codex/sessions/..., which is why the OS returns EISDIR (21). It looks like the in-memory reference to the active thread gets cleared/invalidated while the side chat panel is idle, and on the next request the code path joins an empty thread identifier onto the codex home directory and tries to read the result as a file.

Steps to reproduce

  1. Open Codex.app and use the side chat panel normally (one or more turns).
  2. Leave the side chat panel idle for an extended period (long enough that the app/window goes to background; in my case >30 min, possibly after sleep/wake).
  3. Return to the side chat and send a new message (or trigger any action that creates a task).
  4. The toast error above appears; the message is not sent.

Expected behaviour

The app either:

  • Transparently re-attaches to the previous thread, or
  • Starts a new thread without an error, or
  • Surfaces a recoverable "session expired, start new chat?" prompt — not an internal EISDIR error.

Actual behaviour

Hard error toast; the only workaround is to click "New chat" / reload the window / restart the app.

Workarounds that fix it

  • Clicking + New chat in the side chat panel.
  • ⌘R to reload the webview, or close/reopen the Codex window.
  • Restarting Codex.app.

What's not wrong

  • ~/.codex/sessions/** rollout files are intact and unchanged.
  • auth.json, config.toml, .codex-global-state.json all look healthy.
  • No disk space / permission issue — manually cat'ing any rollout file works fine.

Environment

  • Codex.app version: 26.506.31421 (build 2620)
  • CodexBar: installed (default)
  • OS: macOS, Darwin 25.4.0 (arm64)
  • ~/.codex/ exists and is a regular directory with the standard layout (sessions/, archived_sessions/, auth.json, config.toml, etc.)

Guess at root cause

Somewhere in the thread-store read path, the active thread id/path is "" (or None) after idle, and the code does the moral equivalent of fs::read(codex_home.join(thread_id)) without checking that thread_id is non-empty, so the read targets codex_home itself → EISDIR. A defensive check for an empty/missing thread id (and falling back to "create new thread") should fix it.

Logs

Happy to attach ~/.codex/log/ excerpts if useful — let me know what range / log file you'd like.

What steps can reproduce the bug?

Having any slid chats and waiting

What is the expected behavior?

No response

Additional information

No response

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Desktop app: side chat fails with "failed to read thread /Users/<me>/.codex: Is a directory (os error 21)" after idle