Subagent completion notification shows UUID agent_path instead of nickname in 0.131.0
What version of Codex is running?
0.131.0
Which model were you using?
Observed in a Codex CLI/API-backed session using spawned subagents. The exact model should not be material to the display issue.
What OS are you running?
Linux
What happened?
After upgrading from 0.130.0 to 0.131.0, spawned subagents no longer consistently display their friendly nickname in later notifications/completion events. The spawn response still includes a nickname, but the completion notification surfaces the UUID-like agent_path instead.
Example from a session:
{"agent_id":"019e42da-a5f5-71e0-b291-9b5a86182c89","nickname":"Aristotle"}
Later notification for the same subagent:
{"agent_path":"019e42da-a5f5-71e0-b291-9b5a86182c89","status":{"completed":"..."}}
In 0.130.0, subagent names were displayed as friendly names in this workflow, e.g. famous scientist/mathematician/author-style names. In 0.131.0, the UI/event surface is exposing the stable ID in places where the nickname was expected.
This looks possibly related to #21870, which changed TUI agent metadata hydration to avoid blocking during agent fan-out. That PR says nickname/role metadata is now filled from ThreadStarted and picker refreshes when available. This symptom looks like a fallback path is rendering agent_path/thread ID even though the nickname is available from spawn metadata.
Steps to reproduce
- Run Codex CLI 0.131.0.
- Spawn a subagent.
- Observe that the spawn result includes both an ID and a friendly nickname.
- Wait for the subagent to complete.
- Observe the completion/subagent notification.
Expected behavior
If a subagent nickname is available, subsequent subagent notifications/completion messages should display or include that nickname consistently, with UUID/thread ID as secondary trace metadata at most.
Actual behavior
The later notification displays the UUID-like agent_path instead of the friendly nickname, even though the spawn result included the nickname.
Why this matters
The nickname is much easier to track in multi-agent sessions. Showing raw UUIDs makes subagent status updates harder to scan and appears like a regression from 0.130.0.
Possible cause
This may be a metadata hydration/cache fallback issue introduced by the 0.131.0 TUI/app-server changes, especially #21870. The local receiver-thread cache may not be populated or consulted for the completion notification path, so the renderer falls back to agent_path.
Additional context
This was noticed alongside other 0.131.0 sandbox/TUI behavior changes, but the nickname issue is independent: the subagent itself completed successfully, and the spawn result did include the nickname.
7 Comments
I know this is trivial, but I actually enjoyed seeing the names, even if front-surfacing UUIDs makes debugging complex parallel workflows a much easier query... ymmv, but why not both?
I fully expect this to get lost in Cthulhu's backlog, but an effort was made nonetheless.
Technical Solution
Fix: Subagent Completion Notification Shows UUID agent_path Instead of Nickname
Issue Summary
Bug: After upgrading from 0.130.0 to 0.131.0, spawned subagents no longer consistently display their friendly nickname in completion notifications. The spawn response includes both an
agent_idand a friendlynickname, but the completion notification surfaces the UUID-likeagent_pathinstead.Root Cause: The
collab_agent_metadatacache inChatWidgetmust be populated BEFORE any notification referencing the thread is processed. In 0.131.0, changes from PR #21870 (TUI agent metadata hydration) altered the timing of metadata population. If the completion notification arrives beforeset_collab_agent_metadata()is called for the subagent's thread, the renderer falls back to showingagent_path(UUID) instead of the nickname.Regression: This worked in 0.130.0. The spawn result includes the nickname, but the completion notification path doesn't consult the spawn metadata — it only checks the
collab_agent_metadatacache.Location:
codex-rs/tui/src/chatwidget.rs(metadata cache) +codex-rs/tui/src/app/thread_events.rs(notification handling)---
Root Cause Analysis
Nickname Flow
agent_idandnickname:``
json
``{"agent_id":"019e42da-a5f5-71e0-b291-9b5a86182c89","nickname":"Aristotle"}
ChatWidget::set_collab_agent_metadata()should be called to cache the nickname:``
rust
``self.collab_agent_metadata.insert(thread_id, AgentMetadata {
agent_nickname: Some("Aristotle".to_string()),
agent_role: ...,
});
``
json
`{"agent_path":"019e42da-a5f5-71e0-b291-9b5a86182c89","status":{"completed":"..."}}
collab_agent_metadata(thread_id)The renderer looks up
. If found, displays nickname. If NOT found, falls back toagent_path`.The Bug
In 0.131.0, the metadata cache population was moved to a later point in the lifecycle (PR #21870). If the completion notification arrives before the cache is populated, the renderer falls back to
agent_path.The issue is a race condition between:
set_collab_agent_metadata()(populates the cache)TurnCompletednotification processing (reads the cache)Evidence
agent_pathwhen cache miss occurs---
Proposed Fix
Fix 1: Populate metadata cache from spawn response immediately
File:
codex-rs/tui/src/app/thread_routing.rsor wherever subagent spawn is handledFix 2: Fall back to spawn metadata in completion notification renderer
File:
codex-rs/tui/src/multi_agents.rs(or wherever completion is rendered)Fix 3: Ensure metadata is available from ThreadStarted notification
The
ThreadStartednotification includesagent_nickname. Ensure this is cached before any completion notification can be processed:---
Files Changed
| File | Change |
|------|--------|
|
codex-rs/tui/src/app/thread_routing.rs| Cache metadata immediately on spawn ||
codex-rs/tui/src/app/thread_events.rs| Cache metadata on ThreadStarted notification ||
codex-rs/tui/src/multi_agents.rs| Add spawn metadata fallback in completion renderer ||
codex-rs/tui/src/chatwidget.rs| No change needed (cache API already correct) |---
Risk Assessment
---
Solution developed through automated analysis. Happy to discuss further or provide PR if needed.
I can still reproduce the same class of issue in a current multi-agent session, and #24581 adds a second surface for the same metadata propagation problem.
Fresh examples from today:
That is the desired display contract when nickname/role metadata is available.
In the same session, another spawned subagent fell back to the raw thread id in the transcript history:
And the structured completion notification still exposes only the path/id shape in this surface:
So I think #24581 is correctly a duplicate of this issue, but it is useful evidence that the bug is not limited to the final completion notification. The same metadata loss/fallback can affect spawn/wait/history rendering when the event path has an agent id but not the nickname/role already known elsewhere.
Maintainer-aligned fix shape still seems to be:
Reference from the duplicate issue: candidate fork PR https://github.com/strato-space/codex/pull/1 (
strato-space:fix/subagent-event-labels) implements that metadata propagation path.Update after rebasing the candidate branch onto current upstream
openai/codex:main(8e5f561697):8230ebfac0cff049c47a70543cfdfecb42769700The original one-path fix was too narrow. The updated branch now preserves nickname/role metadata through the app-server
CollabAgentStatefor all collab paths that already carry it: spawn, send-input, wait begin/end, close, and resume. That makes both live TUI rendering and replayed thread history able to label agents asNickname [role]instead of falling back to raw thread IDs.Representative code shape:
For metadata-bearing begin events with no real final status, the branch only uses synthetic
PendingInitwhen nickname/role metadata exists; otherwise it keepsagents_statesempty so legacy UUID fallback behavior is unchanged. For wait-end,agent_statusesis treated as the authoritative metadata-bearing source when present, with legacystatusesused only as the fallback.Fresh validation after the upstream rebase:
Note: a first TUI test attempt after the rebase hit local disk exhaustion (
No space left on device) while rebuilding dependencies; aftercargo cleanfreed space, the same focused TUI test passed.Thanks @jshaofa-ui — I think this diagnosis points in the right direction, but after working through a PR I would frame the fix slightly differently.
Short version: the proposed solution is a good TUI/cache-side explanation of the symptom, but the PR I opened tries to fix the metadata propagation at the app-server/protocol boundary instead of only adding another TUI fallback cache.
Comparison:
| Area | jshaofa-ui proposal | PR approach |
| --- | --- | --- |
| Diagnosis |
ChatWidget.collab_agent_metadatamay be missing when completion notifications render, so the UI falls back toagent_path| nickname/role metadata is not consistently carried throughCollabAgentStatefor live and replayed collab events || Main fix | Populate TUI metadata cache earlier and/or add spawn metadata fallback in renderer | Add optional
agent_nickname/agent_roletoCollabAgentStateand propagate them through event mapping + thread history || Scope | Mostly TUI-local (
chatwidget, routing, renderer) | App-server protocol/schema + live event mapping + replay history + TUI cache hydration || Replay/thread snapshot | Not explicitly covered | Covered via
thread_history.rs|| External app-server consumers | Still may not see nickname in event payloads | Receive nickname/role in the canonical app-server payload |
| Risk | Smaller UI-only patch, but may only treat the symptom | Wider surface/schema change, but optional/backward-compatible and fixes the data plane |
The key distinction is:
That matters because if metadata is lost before reaching TUI, an earlier or additional TUI cache cannot reliably recover it. It also matters for replay/thread snapshots and any non-TUI consumer of the app-server protocol.
So I see the PR as a more general version of the same diagnosis: instead of relying on spawn-time cache timing or renderer fallback, carry the metadata in the canonical event payload and let TUI hydrate its existing navigation/cache from that authoritative metadata.
Current PR: https://github.com/strato-space/codex/pull/1
For an upstream/openai agent that cannot read third-party fork code, here is a clean-room implementation brief to reproduce the fix from first principles.
Task
Fix the multi-agent/collab TUI bug where subagent completion/wait/resume notifications can render the raw UUID-like
agent_path/ thread id instead of the friendly subagent nickname/role.Problem statement
Friendly subagent metadata exists at spawn / collab-agent reference time, but it is not consistently available when later app-server notifications are converted into TUI history/navigation state. When the TUI cannot find metadata for a receiver thread, it falls back to displaying the raw thread id/agent path.
This must work for both:
Clean-room implementation direction
agent_nickname: Option<String>agent_role: Option<String>/ equivalent internal role fieldItemStarted/ItemCompletedcollab tool-call notifications. When an existing receiver thread entry is present, upgrade missing nickname/role only when new metadata is available; do not erase existing metadata withNone.Acceptance criteria
Suggested focused tests
CollabAgentStatecontaining those fields.ItemStartedorItemCompletednotification with metadata creates or upgrades the receiver thread entry with nickname/role.Validation commands
Run the relevant focused Rust tests for:
Then run formatting/diff checks used by the repository.
Current upstream check from
openai/codexmainfae270932065(2026-06-09): this looks partially improved but not fully fixed.Fresh local evidence from a current tmux multi-agent session (
comfy-0:3,omx-supervisor) shows both paths in the same workflow:That is the desired friendly label behavior.
But a later Critic spawn/wait/completion in the same session still fell back to the raw agent/thread id:
So the real current state is: nickname/role propagation works on some surfaces, but UUID fallback is still reachable when the event/rendering path does not carry or prefer the friendly metadata.
I also ran a minimal local
$code-reviewpass over current main, using the repo-localcode-review-*slices. Consolidated findings:codex-rs/app-server-protocol/src/protocol/v2/item.rs:1052—CollabAgentStatestill only carriesstatus/message, so app-server collab items cannot preserve nickname/role for live/replayed consumers. Add optional backward-compatibleagent_nickname/agent_rolefields and regenerate schemas.codex-rs/app-server-protocol/src/protocol/event_mapping.rs:231— live wait completion still maps from legacystatusesand ignores richer metadata-bearing status entries when present, so wait/completion UI can render UUID labels. Prefer the metadata-bearing source when available and fall back to legacy status-only maps only for old events.codex-rs/app-server-protocol/src/protocol/thread_history.rs:641— replay/history conversion drops spawn nickname/role when reconstructing collab items, so thread switch/restored history can still regress to raw IDs. Replay should emit the same metadata-bearing collab state as the live path.codex-rs/core/src/tools/handlers/multi_agents_v2/spawn.rs:154—SubAgentActivityEventappears to drop the nickname computed just above, so downstream activity/completion notifications only getagent_path. Either carry optional nickname/role on the activity event/item or hydrate byagent_thread_idbefore rendering.codex-rs/tui/src/multi_agents.rs:298—sub_agent_activity_history_cellrendersagent_pathdirectly and cannot consult cached nickname/role metadata, unlike collab tool rendering. Prefer nickname/role when known, with path as fallback/trace metadata.codex-rs/tui/src/app/agent_navigation.rs:278— active agent labels currently preferagent_pathoveragent_nickname/agent_role, so a thread with known friendly metadata can still render as the raw path onceagent_pathis recorded. Friendly metadata should be primary; raw path should be fallback.codex-rs/tui/src/app/session_lifecycle.rs:42—/agentstatus previews pass onlyagent_pathintoAgentStatusThreadPreview, so the preview title can discard anAgentPickerThreadEntry's nickname/role. Carry a display label derived from nickname/role and retain path only as fallback/trace metadata.Net: I would keep this issue open until both canonical app-server collab state and the remaining TUI activity/navigation/status surfaces consistently prefer
Nickname [role]whenever metadata is known, while preserving UUID/path as fallback/debug trace.