Skip to content

Trace input contains the instructions preamble instead of the user's prompt (Codex CLI 0.147.0) #47

Description

@nblumoe

Summary

On Codex CLI 0.147.0, the exported trace's input is the injected instructions / environment_context wrapper rather than the user's actual message. output is correct.

Both of the paths in parse.ts that resolve the user's turn miss on this CLI version, so the wrapper ends up in input and the real prompt is never read.

Reproduction

  1. Install plugin tracing@0.1.0 with Codex CLI 0.147.0.
  2. Start a Codex session in a repository that has an AGENTS.md.
  3. Send a short prompt, for example: hi from codex. say "Hi"
  4. Open the resulting trace in Langfuse.

Expected: input is hi from codex. say "Hi"

Actual: input is ~14,000 characters beginning with # AGENTS.md instructions for <path> and ending with </environment_context>. The prompt does not appear anywhere in the trace. output is correct.

Root cause

The rollout for that single turn contains, in order:

  • row 2response_item, payload.type: message, role developer — the instructions
  • row 3response_item, payload.type: message, role user — the injected wrapper (this is what gets exported as input)
  • row 6response_item, payload.type: message, role userthe real prompt
  • row 7event_msg, payload.type: item_completed — carries item.type: "UserMessage" with item.content[].text

1. The primary path never matches

parse.ts:304:

if (et === "user_message" && typeof p.message === "string") {

Codex 0.147.0 emits no event_msg with payload.type === "user_message". The prompt arrives instead as item_completed carrying an item.type === "UserMessage" with item.content[].text (row 7 above).

So turn.userInput is never set, and parse.ts:150 falls through to userInputFallback.

2. The fallback then selects the wrapper

parse.ts:210:

!/^<(environment_context|user_instructions)/.test(text.trim())

The wrapper message is no longer prefixed with <environment_context>. On 0.147.0 it begins with # AGENTS.md instructions for <path> and only ends with </environment_context>, so this anchored test fails and the wrapper is accepted as the fallback.

The !turn.userInputFallback guard on the line above then prevents the real prompt (row 6) from ever replacing it.

Suggested fix

Two changes, both needed independently:

  1. Handle item_completed with item.type === "UserMessage", reading item.content[].text, as a primary source for turn.userInput.
  2. Make the wrapper test content-based rather than prefix-anchored — detect an <environment_context> / <user_instructions> element anywhere in the message, or skip any user message that also carries an instructions preamble.

Fixing only the regex leaves the fallback in use, which stays fragile across CLI versions.

Environment

  • Plugin tracing@0.1.0
  • codex-cli 0.147.0
  • macOS, Node via Homebrew

Traces are otherwise delivered correctly — masking, token usage and the 20,000-character cap all behave as expected. Only the input mapping is affected.

Possibly related

#12 ("some completed Codex sessions produce no sidecar") may share a root cause in rollout parsing, though I have not confirmed that.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions