Codex App pet overlay falls back to idle during active running/waiting/review states

Open 💬 3 comments Opened Jun 18, 2026 by shaharyarmaroof-em

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

26.616.30709 build 4108

What subscription do you have?

ChatGPT plan, exact tier can be filled by reporter

What platform is your computer?

macOS 26.5.1 build 25F80, Apple Silicon / arm64

What issue are you seeing?

In Codex Desktop, the floating pet/avatar overlay does not stay in the active animation state while a task is still running. A custom Codex pet with distinct idle and running rows initially switches to the running row, but after a short burst it falls back to the idle row even though the task is still active.

This makes the pet visually report "idle" during long-running work and removes the distinction between idle and active task states.

Environment observed:

  • Codex App: 26.616.30709 build 4108
  • macOS: 26.5.1 build 25F80
  • Architecture: Apple Silicon / arm64
  • Runtime: desktop app pet/avatar overlay

What steps can reproduce the bug?

  1. Install or select a Codex pet whose atlas has visibly distinct idle and running rows.
  2. Start a task in Codex Desktop that runs longer than a few seconds.
  3. Watch the floating pet overlay.
  4. The pet enters the active running row briefly, then falls back to idle even while the task continues.

I reproduced this with a custom pet package under:

~/.codex/pets/slifer-sky-dragon/
├── pet.json
└── spritesheet.webp

The atlas validates against the current custom pet contract:

  • size: 1536x1872
  • grid: 8 columns x 9 rows
  • row 7 running: non-empty columns 0-5
  • row 0 idle: distinct calm idle animation

Root-cause evidence from the packaged desktop bundle:

The bundled avatar player maps every non-idle state to three cycles of that state followed by the slowed idle loop:

function w(e,t){
  let n=S[e];
  if(t)return{frames:[n[0]],loopStartIndex:null};
  if(e===`idle`)return{frames:x,loopStartIndex:0};
  let r=[...n,...n,...n];
  return{frames:[...r,...x],loopStartIndex:r.length}
}

Because running, waiting, and review are persistent semantic states, this makes them behave like temporary reactions.

What is the expected behavior?

Persistent pet states should loop their own rows until the session/activity state changes:

  • idle loops idle
  • running loops running while a task is active
  • waiting loops waiting while blocked on user input/approval
  • review loops review while in review/inspection state
  • short reactions such as waving, jumping, and possibly failed can continue to fall back to idle

The local fix that validated the behavior was:

function w(e,t){
  let n=S[e];
  if(t)return{frames:[n[0]],loopStartIndex:null};
  if(e===`idle`)return{frames:x,loopStartIndex:0};
  if(e===`running`||e===`waiting`||e===`review`)return{frames:n,loopStartIndex:0};
  let r=[...n,...n,...n];
  return{frames:[...r,...x],loopStartIndex:r.length}
}

After applying this locally to the packaged app bundle and restarting Codex, a 45-second test task kept the pet in the running animation for the duration instead of falling back to idle.

Additional information

Related public issue search found pet/avatar overlay issues, but not this exact state-looping bug:

  • #22625 covers Codex Desktop not reflecting external CLI sessions.
  • #21902 covers reduced-motion causing pets to appear non-animated.
  • #20680 covers pet overlay renderer/GPU load.

This issue is specifically about the animation playback policy for persistent avatar states once the app has already selected the correct state.

View original on GitHub ↗

This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗