Skip to content

Codex: annotate-last fails when one thread spans multiple rollout files #1367

Description

@arklanq-patronus

What happened?

Summary

Running plannotator last in Codex Desktop can fail with:

No rendered assistant message found in session logs.

This happens when one Codex thread is represented by multiple rollout JSONL files. Plannotator may select an empty or aborted rollout even though another rollout for the same thread contains the previous rendered assistant message.

Observed scenario

In the affected Codex thread, several rollout files contained the same thread ID:

  • one rollout was aborted and contained no assistant output_text,
  • another rollout contained the previous rendered assistant response,
  • the active rollout contained the current command.

plannotator last selected the empty rollout and stopped without checking the other matching files.

Debug output, with identifiers redacted:

[DEBUG] Codex detected, thread ID: <redacted>
[DEBUG] Rollout: ~/.codex/sessions/YYYY/MM/DD/rollout-...<thread-id>_<segment-id>.jsonl
No rendered assistant message found in session logs.

Steps to reproduce

  1. Open a task in Codex Desktop.
  2. Continue or resume it until Codex creates multiple rollout files associated with the same thread ID.
  3. Ensure one matching rollout is empty or aborted while another contains a completed assistant response.
  4. Run plannotator last.
  5. Plannotator may select the empty rollout and return the error above.

I do not yet have a deterministic sequence that always makes Codex split a thread into multiple rollout files, but this structure occurred in a real Codex Desktop task.

Expected behavior

Plannotator should treat all rollout files belonging to the current Codex thread as one logical conversation and open the most recent completed assistant response before the active turn.

Actual behavior

Plannotator selects one matching rollout file and fails immediately when that file does not contain a rendered assistant message, even though another rollout for the same thread does.

Likely root cause

findCodexRolloutByThreadId() returns the first filename from readdirSync() that contains the thread ID:
https://github.com/backnotprop/plannotator/blob/main/apps/hook/server/codex-session.ts

The candidates are not ordered or inspected before one is selected. Therefore, when several rollout files match the same thread, filesystem iteration order determines which rollout is used.

Plannotator version

plannotator 0.27.1

OS

macOS

Agent

Codex

Where did it happen?

Annotate

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions