Skip to content

Compacted replacement_history retains active startup/context packets, duplicating AGENTS/developer/memory/skills context #21269

Closed

Description

@macintog

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

Version 26.429.61741 (2429)

What subscription do you have?

Pro

What platform is your computer?

Darwin 24.6.0 arm64 arm

What issue are you seeing?

Codex compaction appears to preserve active startup/context instruction packets inside payload.replacement_history as if they were ordinary conversation history. On the next turn, those same instruction surfaces are also supplied again through the normal active turn-context path.

This creates a large fixed post-compaction prompt floor before any meaningful new work is added. In one representative Codex Desktop session, the first post-compaction request started at 33,093 input tokens with only 3,456 cached, leaving about 29,637 uncached input.

This is not just “my local startup packet is large.” Larger local memory/skills payloads make the symptom easier to measure, but the underlying bug is independent of that size: active startup/context packets should not be retained in compacted history and then supplied again as active context. Any user with AGENTS/project instructions, developer context, plugins, skills, or memories can pay the same duplicated-context cost at smaller scale.

Impact is cost/headroom and possible steering risk: retained startup/context packets appear as history while current versions are also supplied through the active instruction path.

Representative session:

/Users/<user>/.codex/sessions/2026/05/05/rollout-2026-05-05T12-43-22-019df905-d546-7100-b619-4571226c3b53.jsonl

Representative cwd:

/Users/<user>/work/repo-with-agents

Representative compaction timestamp:

2026-05-05T17:22:37.986Z

In the type == "compacted" record:

  • payload.message == ""
  • replacement_history entries: 9
  • serialized replacement_history size: 98,519 bytes
  • retained developer text: about 58.9 KB
  • retained AGENTS wrapper text: about 16.1 KB
  • largest retained developer sections: memory about 26.6 KB, skills about 24.0 KB, app context about 3.5 KB

Token counts around compaction, from last_token_usage:

  • before compaction: 221,525 input, 220,032 cached
  • first nonzero post-compaction request: 33,093 input, 3,456 cached
  • first post-compaction uncached input: about 29,637

Redacted proof shape:

  • payload.replacement_history[N].role == "user" contains # AGENTS.md instructions...
  • the normalized/hash of that AGENTS body matches the adjacent turn_context.user_instructions
  • payload.replacement_history[M].role == "developer" contains <app-context>, ## Memory, and <skills_instructions>
  • the adjacent post-compaction turn_context also contains current active context surfaces

I can provide exact redacted hashes privately if useful.

What steps can reproduce the bug?

  1. Start a Codex Desktop thread in a repo with an AGENTS.md.
  2. Use normal startup/context surfaces, especially skills and/or memories if available.
  3. Drive the thread to compaction.
  4. Inspect the session JSONL type == "compacted" event.
  5. Check whether payload.replacement_history contains:
    • a user item with # AGENTS.md instructions...
    • a developer item containing <app-context>, ## Memory, <skills_instructions>, or plugin/app instructions
  6. Inspect the adjacent turn_context.
  7. Compare whether the AGENTS body is also present in turn_context.user_instructions.
  8. Inspect the first post-compaction event_msg / token_count.
  9. Confirm whether post-compaction input remains high before new work is added.

Focused scan:

  • window: 2026-04-28T00:00:00Z through 2026-05-05T23:59:59Z
  • 70 compactions across 34 session files
  • 63/70 compactions retained developer/app-context packets
  • 63/70 retained # AGENTS.md instructions... wrappers
  • 63/63 normal compactions with an AGENTS wrapper contained the same body already present in turn_context.user_instructions
  • 63/70 retained skills instruction markers
  • 36/70 retained memory sections
  • replacement history size: median 107,290 bytes, p95 1,130,774, max 1,470,356
  • first post-compaction input tokens: median 32,514, max 90,411

Broader scan across all available local sessions:

  • 1,015 compaction events across 479 session files
  • retained AGENTS/developer packet pattern observed across every week with compactions in the local corpus
  • Desktop: 938/986 compactions included retained AGENTS wrappers and developer packets
  • TUI: 22/29 compactions included retained AGENTS wrappers and developer packets
  • earliest retained AGENTS sample observed:
    2026-02-27T21:18:49.602Z, Codex Desktop 0.105.0, cwd /Users/<user>/work/another-repo-with-agents

The retention pattern predates my recent local startup/config setup. Later memory/skills configuration amplified the duplicated payload size but did not create the underlying compaction behavior.

What is the expected behavior?

After compaction, replacement_history should contain compacted conversational history and/or the compaction summary.

It should not retain raw current startup/context packets when those same surfaces are already supplied through active turn context on the next request.

After compaction:

  • replacement_history does not contain raw active AGENTS/developer/memory/skills/app/plugin startup packets
  • active startup/context surfaces are still present exactly once in the next model request
  • first post-compaction prompt size reflects compacted conversation state plus one current context injection, not duplicated startup/context payload
  • disabling memories/skills may reduce baseline size, but should not be required to avoid duplication

Additional information

Related prior work:

Local mitigation tests:

Measured with:

codex debug prompt-input 'probe'

From /Users/<user>/work/repo-with-agents:

  • default: 76,270 serialized prompt bytes
  • -c features.memories=false: 49,302 bytes
  • -c memories.use_memories=false: 49,302 bytes
  • -c skills.include_instructions=false: 52,097 bytes

These mitigations reduce the size of my local duplicated payload. They do not address the general bug: active context should not be copied into replacement_history and re-sent as history for any user.

I can provide the representative JSONL privately if useful. I am not attaching the full session publicly because it contains local paths and model-visible context, but the event paths, timestamps, counts, and reproduction checks above are exact.

Activity

  1. added
    appIssues related to the Codex desktop app
    on May 5, 2026
  2. added
    bugSomething isn't working
    contextIssues related to context management (including compaction)
    sessionIssues involving session (thread) management, resuming, forking, naming, archiving
    on May 5, 2026
  3. mahdikayvan commented on May 10, 2026

    @mahdikayvan

    @macintog Hey — I felt this issue immediately, and it is very close to the exact pain I’m trying to solve.

    I’m building AgaveCore, and I’d like to let a few early people use it for free while I shape it into something stronger.

    It helps when a coding agent starts to drift, loses important context, or gives you an output you do not fully trust.

    In practice, it works through two habits:

    • tell the agent to remember-progress or remember-this when something important should not be lost
    • use consult-brain when the current task needs more grounded feedback on what to do next

    Over time, as useful journals, decisions, and failures pile up, the product should help the agent make sharper decisions and take better actions with less drift.

    If this sounds relevant, reply here and I’ll send the exact steps. You can also use the email or Telegram on my profile.

    Cheers,
    Mads.

  4. glindstr commented on May 20, 2026

    @glindstr

    I'm also running into this bug and it is a significant issue. Is this getting any traction?

  5. ryuhmanov-m commented on May 26, 2026

    @ryuhmanov-m

    Draft GitHub Comment - Codex Context Compaction

    Target issue: #21269

    Secondary issue worth linking, but not duplicating the full comment: #11072

    Adding another affected-user report with local JSONL evidence from Codex Desktop.
    
    This is not just an occasional expected compaction near the model limit. The current behavior makes normal agent work very hard because short image/tool-heavy phases can trigger multiple compactions in quick succession, and the compaction itself appears to preserve payloads that should not be retained as conversation history.
    
    Environment:
    
    - Product: Codex Desktop
    - CLI/runtime in session metadata: `0.133.0-alpha.1`
    - Model: `gpt-5.5`
    - Reasoning: `xhigh`
    - Platform: macOS
    - Config had `model_context_window = 1050000` and `model_auto_compact_token_limit = 900000`
    - Actual token-count events still reported `model_context_window = 258400`
    - `codex debug models` reports `gpt-5.5 context_window = 272000`, `max_context_window = 272000`, `effective_context_window_percent = 95`
    
    Observed recent session:
    
    - The active prompt reached `222,105 / 258,400` input tokens before the first compaction.
    - Later in the same work burst it reached `242,584 / 258,400` before another compaction.
    - From the user perspective this was one short screenshot/artifact workflow, not a long multi-day session. The visible experience was multiple "context automatically compacted" transitions after a small amount of new work.
    
    Root-cause evidence from the session JSONL:
    
    - `view_image(detail="high")` outputs were persisted as inline `input_image` payloads with `data:image/png;base64,...`.
    - There were `51` `data:image/png;base64` occurrences in the affected session file.
    - The largest image tool outputs were serialized as roughly `1.8M`, `1.34M`, `978k`, and `971k` characters.
    - The first `type == "compacted"` event retained a `replacement_history` of about `353k` serialized characters.
    - That compacted replacement history retained:
      - the original user screenshot as an inline `input_image` with about `283k` chars of base64 URL
      - developer/startup context
      - `# AGENTS.md instructions`
      - `<skills_instructions>`
      - `## Memory`
    - The next turn then also receives fresh active context, so this creates a large fixed post-compaction floor and preserves old image/context payloads that are no longer useful.
    
    Broader local scan:
    
    - Local 2026 corpus: `1383` rollout JSONL files, about `9.4G` under `.codex/sessions`
    - `486` files contained `type == "compacted"` events
    - `2040` total `type == "compacted"` events
    - `952` compaction events across `252` files retained `data:image`
    - `1191` compaction events across `325` files retained `# AGENTS.md instructions`
    - `551` compaction events across `146` files retained `<skills_instructions>`
    - `549` compaction events across `145` files retained `## Memory`
    
    Why this is severe:
    
    - Image/tool-heavy work is a common Codex Desktop workflow, especially browser/screenshot/frontend validation.
    - The user does not experience this as "I used 250k tokens intentionally"; they experience it as one request or one small workflow causing repeated automatic compactions.
    - After compaction, retaining startup/context packets and old inline images reduces the headroom that compaction is supposed to recover.
    - With `gpt-5.5`, local `model_context_window`/`model_auto_compact_token_limit` settings do not appear to override the model/runtime limit, so users cannot mitigate this by raising the limit.
    
    Expected behavior:
    
    - Tool screenshots/images should not be stored or re-sent as huge base64 blobs when a file reference or image handle would be sufficient.
    - Compacted `replacement_history` should not retain raw active startup/context packets such as AGENTS/developer/memory/skills when those are already supplied as active context on the next turn.
    - Compaction should remove stale image payloads that are no longer useful to the current task.
    - The Desktop UI should make the effective model context window clear, especially when config values are being clamped by the selected model.
    
    I can provide a redacted session summary or specific counters if useful, but I cannot attach the raw JSONL publicly because it contains local paths, prompts, and project context.
  6. etraut-openai commented on Jun 29, 2026

    @etraut-openai
    Contributor

    Thanks for reporting this problem. Until recently, Codex used a separate endpoint and server-side logic for compaction. We recently switched to a more robust approach where the compaction logic is moved locally using the same endpoint as normal turns. This eliminates "remote compaction" errors and increases the stability and reliability of compaction operations. If you see further problems with compaction, please use /feedback and open a new bug report.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    appIssues related to the Codex desktop appbugSomething isn't workingcontextIssues related to context management (including compaction)sessionIssues involving session (thread) management, resuming, forking, naming, archiving

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions