Codex Desktop pet tray omits active threads and shows inconsistent thread status
Environment
- Codex Desktop: 26.519.41501
- Platform: macOS
- Pet: BSOD
- Observed: 2026-05-24 around 06:26-06:32 UTC / 10:26-10:32 Asia/Dubai
Expected
The pet tray should reflect the same active/recent in-flight threads as Codex Desktop's local thread/session state, and statuses should be consistent across comparable threads.
Actual
The pet tray showed only two thread cards:
- Thread A: current diagnostics thread
- Thread C: a routing task thread
But local Codex state showed three fresh, non-archived, non-final threads:
- Thread A: current diagnostics thread, updated 06:31:58 UTC, visible in pet
- Thread B: profile-menu task thread, updated 06:31:56 UTC, missing from pet
- Thread C: routing task thread, updated 06:31:39 UTC, visible in pet
Thread B was missing from the pet tray even though it was updated at almost the same time as Thread C.
At the screenshot time window, Thread B and Thread C had very similar session state:
- latest assistant phase:
commentary - latest event:
token_count - no
final_answer - no
task_complete
So the pet tray appears to apply inconsistent filtering: one unfinished/recent thread is shown, another similar unfinished/recent thread is hidden.
Local evidence
~/.codex/state_5.sqlite showed the three newest non-archived threads updated within ~20 seconds of each other.
~/.codex/sessions/2026/05/24/*.jsonl showed:
- completed older thread:
final_answer/task_complete, correctly absent from pet - Thread C:
commentary/token_count, visible in pet - Thread B:
commentary/token_count, missing from pet - Thread A: visible in pet
Desktop logs also showed the missing Thread B conversation was created and registered as a browser sidebar thread:
- created at 06:16:03 UTC
- registered at 06:16:03 UTC
- continued receiving route/session events around 06:30-06:32 UTC
Why this matters
The pet becomes unreliable as a "what is still running / waiting / ready" surface. In this case it hid a likely active/recent non-final thread while showing another thread with comparable local state.
Related but not identical
- #22112
- #22625
- #21348
- #12321
This does not look like the external CLI case: the affected threads are local Codex Desktop/App threads, and the mismatch is between the pet tray and local Codex thread/session state.
8 Comments
Solution: Fix Codex Desktop Pet Tray Omitting Active Threads
Issue: openai/codex #24302
Labels: bug, app, session, pets
Component: Pet Tray State Synchronization
---
1. Problem Statement
The Codex Desktop pet tray (system tray indicator) shows only a subset of active threads, omitting threads that are confirmed active in the local Codex session state. Specifically:
This is a state synchronization bug where the pet tray's data source fails to reflect the complete set of active threads.
---
2. Root Cause Analysis
2.1 Architecture Overview
The pet tray is a native OS system tray indicator (macOS menu bar / Windows notification area) that displays thread status cards. It receives thread state updates through a subscription/observer pattern from the main application state.
Data Flow:
2.2 Likely Root Causes (ranked by probability)
Cause A: Subscription Race Condition (Most Likely)
ThreadCreatedeventsEvidence:
Cause B: Thread State Filtering Bug
thread.status !== 'archived' && thread.status !== 'final' && thread.hasUICause C: State Update Throttle/Debounce Bug
---
3. Proposed Fix
3.1 Primary Fix: Ensure Complete Thread Subscription
File:
src/main/pet-tray/pet-tray-controller.ts(or equivalent Rust/Tauri path)3.2 Secondary Fix: Remove Overly Aggressive Filtering
File:
src/main/pet-tray/thread-filter.ts3.3 Tertiary Fix: Add Reconciliation Mechanism
Add a periodic reconciliation that compares pet tray state against session manager state:
---
4. Testing Strategy
Unit Tests
Integration Tests
Manual Testing
---
5. Impact Assessment
---
6. Files to Modify
| File | Change |
|------|--------|
|
src/main/pet-tray/pet-tray-controller.ts| AddonThreadCreatedsubscription + initial sync ||
src/main/pet-tray/thread-filter.ts| Remove overly aggressive filtering ||
src/main/pet-tray/reconciliation.ts(new) | Add periodic state reconciliation ||
tests/pet-tray.test.ts| Add regression tests |---
7. Estimated Effort
I was just about to talk about this, the pets only sow the messages if the chat is new, but it never shows follow-up messages.
Yeah synchronization of the pet with what's going on is lost pretty quickly, making the whole feature useless until this is fixed!
I can reproduce this deterministically in desktop build
26.707.41301on macOS 26.3 (Darwin 25.3.0 arm64).Deterministic trigger
updatedAttimestamp (for example, a long quiet command/tool operation).runningand the task is still working.updatedAtcan make it reappear temporarily.Root cause observed in the installed renderer
The session-to-notification filter computes an expiry for every non-idle status. For
running, the expiry is hard-coded to:Once
Date.now()reaches that value, the notification is omitted without first checking whether the session still hasstatus === "running". The tray may refetch session data, but a quiet task retains the oldupdatedAtMs, so refetching does not prevent expiry.This explains why synchronization is "lost pretty quickly": the tray is treating a live running state as a stale notification.
Expected fix
Running sessions should remain visible until their status changes. At the expiry switch, the minimal behavior would be equivalent to:
TTL behavior can remain for terminal/unread states such as failed or review. This would also match the documented pet status semantics: Running — A task is actively working.
Confirmed this is still present in Codex Desktop
26.707.72221(build5307) on macOS26.5.2(25F84, Apple Silicon).Observed behavior: the pet activity tray tracks only a subset of currently active local chats; long-running/quiet chats disappear even though their tasks are still active in Codex.
Fresh bundle check on this build shows the same live-session expiry described above is still shipped:
The notification filter then removes the session when
Date.now()reaches that timestamp without first checking that the session is stillrunning. The overlay is also built from a recent-conversations view rather than an explicit reconciled inventory of all non-idle threads.This is therefore not a spritesheet/custom-pet packaging problem. A durable fix should keep every live
running/waitingsession present until its actual status changes and reconcile the tray against the complete active-thread set after subscriptions/refetches.Pets are actually a very strong codex feature for me - helps with context switching, especially while working with tasks in parallel, keeping track of what's currently active for me and what's done is essential while I distract for something else, waiting for Codex to finish current scope. Helps maintaining that gentle context awareness, and task switching is suddenly no that painful.
However, it only works when it's consistent in what it shows. Currently, it's completely not. So thumbs up for fixing please!
I can reproduce this on macOS with Codex Desktop 26.715.31925.
I often have multiple tasks actively running at the same time, but the Pet activity tray shows only a subset of them. The missing tasks are still running normally in the main Codex UI, so the Pet cannot currently be relied on to monitor parallel tasks.
This appears consistent with the active-thread synchronization and expiry behavior described in this issue.
Yup, things still just "disappear" when tasks are in flight (tried to identify if it was when windows were switching or after a certain time but didn't find anything yet).
Unfortunately defeats the purpose of having it at all which is a shame!