openai / openai/codex

Overriding reminder_threshold_tokens silently drops model-provided handoff guidance and fallback

Open
#42,918 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug CLI config context
Dominant language
Rust
Stars
125k
Forks
19.4k
PR merge metrics
PR metrics pending

Description

What version of Codex CLI is running?

Reproduced with codex-cli 0.153.1 bundled in the macOS app and the official standalone codex-cli 0.153.4 release binary. The latter was downloaded into a temporary directory and its SHA-256 was checked against the GitHub release asset digest.

What subscription do you have?

ChatGPT subscription authentication, using the Codex backend; not API-key authentication or a custom provider.

Which model were you using?

gpt-5.6-luna. Its model catalog supplied nonempty token-budget guidance and fallback prompts. At the time of testing, the catalog specified reminder_threshold_tokens = 6144 and auto_compact_fallback_buffer_tokens = 16384.

What platform is your computer?

Darwin 25.6.0 arm64 arm.

What issue are you seeing?

With experimental context management enabled, changing only features.token_budget.reminder_threshold_tokens disables inheritance of the other model-provided token-budget settings. A user trying to receive an earlier handoff reminder can therefore silently lose the handoff guidance and fallback configuration that make summary-free context rollover usable.

This is a configuration-resolution issue, independently observable without filling a context window or sampling a model response.

What steps can reproduce the bug?

Preconditions: use eligible ChatGPT authentication, a model whose catalog supplies token-budget guidance, and no existing detailed [features.token_budget] overrides.

Run these two prompt-rendering checks. The only configuration difference is the reminder threshold. The filter emits a boolean, not private prompt contents.

codex -m gpt-5.6-luna \
  -c features.context_management.experimental_mode=true \
  debug prompt-input 'Configuration merge probe.' \
  | python3 -c 'import sys; print("<context_window_guidance>" in sys.stdin.read())'

codex -m gpt-5.6-luna \
  -c features.context_management.experimental_mode=true \
  -c features.token_budget.reminder_threshold_tokens=14000 \
  debug prompt-input 'Configuration merge probe.' \
  | python3 -c 'import sys; print("<context_window_guidance>" in sys.stdin.read())'

Observed on both tested versions:

Check Model defaults Only threshold overridden
Command exit status 0 0
<context_window> present true true
<context_window_guidance> present true false

Both checks ran against the same local configuration and model selection. The configuration file hash was unchanged before and after each A/B pair. No long-running task or forced rollover is needed to reproduce this prompt-level difference.

What is the expected behavior?

A scalar timing override should retain unspecified model-provided guidance, reminder text, fallback prompt, and fallback buffer. Changing how early to remind the agent should not implicitly opt out of the rest of the handoff mechanism.

If whole-object replacement is intentional, please expose that explicitly and warn or reject incomplete handoff configurations instead of silently accepting this combination.

Additional information

The code explains the result:

  1. has_explicit_settings returns true for any token-budget key other than enabled and use_history_notes_extension.
  2. TurnContext construction then sets use_model_token_budget_defaults to false.
  3. resolve_token_budget returns the user-configured object directly rather than merging unspecified fields with the model defaults.
  4. TokenBudgetConfig::default leaves guidance_message, auto_compact_fallback_prompt, and the fallback buffer unset. The reminder template also falls back to a generic built-in template rather than the model-provided one. Thus a reminder can still exist while the richer guidance and fallback are absent.

The same resolution path is present in the inspected rust-v0.153.4 source and public main.

A separate small-window synthetic subagent test showed the practical risk: with a threshold-only override and no successful checkpoint, automatic rollover discarded the task state and the agent asked what to work on. A later test retaining the full model defaults and explicitly checkpointing early completed two rollovers correctly. Those two task runs changed additional conditions, so they are supporting context, not a single-variable causal experiment. The prompt-rendering A/B above is the isolated reproduction.

Related but broader reports: #36642 (task loss after automatic compaction) and #42449 (handoff requirements without available tools). This report isolates the partial-configuration merge behavior even when the history/notes backend is available. A regression test for a model with nonempty defaults plus only a reminder-threshold override would cover this case.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with codex-rs/core/src/session/token_budget.rs and turn_context.rs, then inspect TokenBudgetConfig::default in codex-rs/core/src/config/mod.rs. Run the two debug prompt-input checks from the issue and add a regression test for model defaults plus only a reminder-threshold override. Done means the override changes the threshold while retaining model-provided guidance, fallback prompt, and fallback buffer.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
74/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.