Failed to read thread goal: thread/goal/get failed in TUI

Resolved 💬 3 comments Opened May 22, 2026 by mzhaom Closed May 30, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

What version of Codex CLI is running?

v0.132.0

What subscription do you have?

max

Which model were you using?

gpt-5.5

What platform is your computer?

linux

What terminal emulator and version are you using (if applicable)?

tmux

Codex doctor report

What issue are you seeing?

running a goal hit an error

Failed to read thread goal: thread/goal/get failed in TUI

/clear didn't help.

What steps can reproduce the bug?

Uploaded thread: 019e51ab-0630-7022-99ac-e95bf4da526a

What is the expected behavior?

_No response_

Additional information

_No response_

View original on GitHub ↗

3 Comments

github-actions[bot] contributor · 3 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #23984
  • #23755

Powered by Codex Action

mitre88 · 3 months ago

Took a closer look at the code path that produces this error message; sharing analysis in case it's useful, since the displayed string is a known anti-pattern in the rest of this crate.

Why the message is uninformative

The literal "Failed to read thread goal: thread/goal/get failed in TUI" is produced here:

  • codex-rs/tui/src/app/thread_goal_actions.rs:289-296

``rust
fn thread_goal_error_message(action: &str, err: &color_eyre::Report) -> String {
if is_ephemeral_thread_goal_error(err) {
EPHEMERAL_THREAD_GOAL_ERROR_MESSAGE.to_string()
} else {
format!("Failed to {action} thread goal: {err}")
}
}
``

  • The err originates at codex-rs/tui/src/app_server_session.rs:788-802, where the wire failure is wrapped with .wrap_err("thread/goal/get failed in TUI"). Sister methods at L823 (thread/goal/set) and L839 (thread/goal/clear) do the same.

The reason the user only sees the wrap message and nothing underneath is that Display on color_eyre::Report ({err}) prints only the outermost context, so the underlying cause from the app-server transport / deserialization / server-side failure is silently dropped. The alternate selector {err:#} collapses the full chain inline.

This is already the established convention in the same crate — every other equivalent error surface uses the alternate selector:

  • codex-rs/tui/src/app.rs:619 — .map_err(|err| format!("{err:#}"))
  • codex-rs/tui/src/app/background_requests.rs:93 — .map_err(|err| format!("{err:#}"))
  • codex-rs/tui/src/app/thread_routing.rs:741,743 — format!("{failure_message}: {err:#}")
  • codex-rs/tui/src/startup_hooks_review.rs:54 — tracing::warn!("…: {err:#}")

So thread_goal_error_message is the only outlier among TUI error surfaces, which is why /goal failures present without their root cause and the other surfaces don't.

Suggested patch (docs-only-ish, ~1 line of semantic change)

--- a/codex-rs/tui/src/app/thread_goal_actions.rs
+++ b/codex-rs/tui/src/app/thread_goal_actions.rs
@@ -289,7 +289,7 @@ fn thread_goal_error_message(action: &str, err: &color_eyre::Report) -> String
     if is_ephemeral_thread_goal_error(err) {
         EPHEMERAL_THREAD_GOAL_ERROR_MESSAGE.to_string()
     } else {
-        format!("Failed to {action} thread goal: {err}")
+        format!("Failed to {action} thread goal: {err:#}")
     }
 }

This covers all seven thread_goal_error_message(...) call sites in thread_goal_actions.rs (lines 35, 100, 137, 154, 184, 214, 242 — read / replace / update / clear / generic action).

Why this matters for triage of this exact issue

With the patch applied, the message in this bug report would have instead read something like:

Failed to read thread goal: thread/goal/get failed in TUI: <transport error / server-side reason>

…which is what's needed to actually diagnose what went wrong on thread 019e51ab-0630-7022-99ac-e95bf4da526a. Right now the chain truncation is hiding the real failure from both the user and any subsequent bug report.

Validation

  • cargo check -p codex-tui
  • just test -p codex-tui — the existing snapshot tests (thread_goal_ephemeral_error_message_renders_snapshot, thread_goal_error_message_preserves_generic_failure_context at L327-372) intentionally exercise both the ephemeral branch and the generic-wrap branch; the generic test currently asserts Failed to read thread goal: thread/goal/get failed in TUI, so it would need updating to assert the alternate-form chain (e.g. Failed to read thread goal: thread/goal/get failed in TUI: server disappeared). That snapshot adjustment is the only other change required.

Posting this as analysis rather than opening an unsolicited PR per docs/contributing.md. Happy to put up an invited PR with the patch + snapshot update if a maintainer thinks the direction is right.

etraut-openai contributor · 3 months ago

This should now be fixed in the latest version. If you're still seeing this problem with 0.134.0 or newer, let us know.