Skip to content

ocx sync overwrites user edits in ~/.codex/config.toml (default subagent, context windows, effort defaults) #7425

Open

Description

@RHODIZSECURITY

Client or integration

Codex CLI

Area

CLI

Summary

ocx sync overwrites user edits in ~/.codex/config.toml. After setting a default subagent model, per-target context-window declarations (modelContextWindows = 1000000 for the combo targets in the Codex catalog) and combo effort defaults, running ocx sync reverts or removes those user settings. We expected sync to preserve user-owned keys it does not manage (merge instead of overwrite). Current workaround: a systemd ExecStartPost hook that re-applies our settings after every OpenCodex service start. Reported by RHODIZ IT LLC (production homelab: VM instance + laptop install).

Reproduction

  1. Point Codex at OpenCodex and set user preferences: default subagent model and modelContextWindows declarations in the Codex config/catalog, plus defaultEffort on the combos in the OpenCodex config.
  2. Run ocx sync.
  3. Observe: the default subagent and the context-window declaration in ~/.codex/config.toml are reverted/removed; combo effort defaults revert as well.
  4. Re-apply the settings by hand; the next ocx sync removes them again.

Version

2.84.0 (VM instance). The config clobbering was also observed on a 2.86.0 laptop install.

Operating system

Linux (Ubuntu Server VM); also observed on a Windows laptop install.

Provider and model

Not provider-specific: affects combo routes generally (for example routes fronting Antigravity accounts).

Logs or error output

No error is emitted; sync completes successfully. The observable evidence is the before/after diff of ~/.codex/config.toml: user-set keys present before ocx sync are absent or reverted after it. Our production mitigation (a systemd ExecStartPost hook re-applying the settings on every start) exists solely because of this behavior.

Screenshots and supporting files

None — this is CLI/config behavior; full detail is in Summary, Reproduction and Redacted configuration.

Redacted configuration

{
  "~/.codex/config.toml (user-owned keys reverted by sync)": [
    "default subagent model = <user choice>",
    "modelContextWindows for combo targets = 1000000"
  ],
  "~/.opencodex/config.json (combo defaults reverted by sync)": [
    "defaultEffort = <user choice>"
  ]
}

Checks

  • I searched existing issues and documentation.
  • I removed secrets, tokens, account details, request credentials, and personal data.

Activity

  1. github-actions commented on Oct 20, 2026

    @github-actions
    Contributor

    Automated translation bookkeeping — detected language: English.

  2. github-actions commented on Oct 20, 2026

    @github-actions
    Contributor

    Issue reopened

    The report now contains the information required by the automated check. Thanks for updating it.

  3. changed the title [-]ocx sync overwrites user config in ~/.codex/config.toml; plus 429 account rotation and missing-usage synthesis[/-] [+]ocx sync overwrites user edits in ~/.codex/config.toml (default subagent, context windows, effort defaults)[/+] on Oct 20, 2026
  4. added
    bugSomething isn't working
    platformOS/service/tray/ACL (Windows-heavy, not Windows-only)
    on Oct 20, 2026
  5. Ingwannu commented on Oct 20, 2026

    @Ingwannu
    Owner

    Checked against trusted dev 12025981e5a304cdb6b1b54f525ba8554f623977. The report uses conceptual names rather than exact serialized keys: provider modelContextWindows, generated Codex catalog context_window and Codex TOML settings have different owners. Please attach a minimal redacted before/after diff with the exact table/key paths and operation order for each file, plus the effective integration/ownership state. A narrow fixture can then prove preservation of foreign keys and deliberate replacement of managed keys. No need for full configs or credentials, and no live sync should be used as a reproduction here. This remains open rather than assuming all three reported settings share one writer.

  6. lidge-jun commented on Oct 28, 2026

    @lidge-jun
    Owner

    Investigation against dev at fdc6dd82d, using isolated fixture homes only (no live sync).

    Result: no remaining overwrite of a key that ocx sync does not own was reproduced. #7659 (e9df82cb5, on dev) already fixed the two cases this report describes: per-target context windows and an edited native subagent default. Eleven fixture scenarios ran the real injector and the local sync/catalog writer repeatedly, with LF and CRLF configs.

    What sync owns in ~/.codex/config.toml (edits are source-span edits, so foreign keys and comments survive):

    Area Behaviour
    Root routing Refreshes its own openai_base_url / experimental_realtime_ws_base_url and preserves unmarked user overrides. Removes root model_provider, or sets it to opencodex in provider-table mode.
    Reserved tables Regenerates [profiles.opencodex] and [model_providers.opencodex]; other profile and provider tables are untouched.
    Catalog pointer Manages model_catalog_json only when it points at opencodex-catalog.json.
    Policy switches service_tier, [features].fast_mode, web_search (sidecar off) and [features].multi_agent_v2 (explicit V1) follow OpenCodex settings.
    Native subagent defaults Only with syncCodexSubagentDefaults on, and only marker-tagged [agents].default_subagent_model / default_subagent_reasoning_effort. An unmarked value is never touched. A marked value you edited is adopted as yours while the journal still records the original write (src/codex/subagent-defaults.ts:24).
    Everything else Root model, model_context_window, model_auto_compact_token_limit, unknown keys and tables, other [agents] settings and role config_files were preserved in every fixture.

    Where each reported setting actually lives:

    • Per-target context windows belong in ~/.opencodex/config.json at providers.<provider>.modelContextWindows.<model-id> (src/codex/catalog/model-hints.ts:174). A combo's window is the minimum of its members' windows, written into the generated catalog's context_window. Hand edits to the generated catalog are regenerated on the next sync by design; a modelContextWindows key in TOML is not read as this setting.
    • combos.<id>.defaultEffort is read, never written, by sync (src/codex/catalog/aggregation.ts:179). In the fixtures its JSON bytes were unchanged. Sync can still save config.json for model-discovery bookkeeping (modelDiscovery / disabledModels, src/codex/catalog/retained-sync.ts:690), so the claim is narrower than "sync never writes JSON".

    One open edge: if a marked subagent default was edited and the journal is missing, the marker alone decides and the value is replaced. That is current policy, and it is the case to look at if the report still reproduces after #7659.

    To take this further we need a minimal redacted before/after diff (exact table/key paths; no tokens or full config files):

    1. Which subagent field changed: [agents].default_subagent_model, a role's config_file model, a profile, or another path? Did the value carry an OpenCodex marker comment?
    2. Where were the windows set: provider JSON, a TOML key, or the generated catalog (which file and row)?
    3. Which combos.<id>.defaultEffort values changed on disk, and was anything else (GUI, CLI, the reapply hook) writing config.json around the sync?
    4. OpenCodex and Codex versions, standalone vs connected client vs Link/Home, and whether syncCodexSubagentDefaults is on.
    5. Does it still reproduce on a build that includes fix(codex): preserve sync edits with canonical sandbox checks #7659, with the ExecStartPost reapply hook disabled?

    With a fragment that reproduces, the next step is an isolated failing regression before any ownership change.

  7. lidge-jun commented on Oct 30, 2026

    @lidge-jun
    Owner

    Triage against current dev (4fc870074), from source and the existing regressions. No live sync was run against a reporter config.

    Fixed by #7659 (e9df82cb5):

    • Root model_context_window in ~/.codex/config.toml is preserved across sync and restore. See src/codex/inject/plan.ts and the regression in tests/codex-integration/codex-sync-user-edits.test.ts.
    • A marked default_subagent_model / default_subagent_reasoning_effort value that differs from the value recorded in the injection journal is adopted as user-owned instead of reverted. This holds on update and on removal, including multiline strings. Unmarked values were already user-owned.

    Still possible, by design today: when the journal has no recorded value for a marked default, the marker alone decides. For example, an install whose journal predates #7659, or one whose journal was removed. A hand-edited value that kept its # Managed by opencodex marker is then replaced on the next sync. src/codex/subagent-defaults.ts documents this ("Absent means no evidence, and the marker alone decides"), and the test "without a journaled record the marker alone decides, as before" pins it. Changing it is a product decision: treating unrecorded marked values as user-owned would also stop updating legacy defaults OpenCodex really did write. Workaround: delete the marker line above your edited value, which makes it user-owned on every later sync.

    Not reproduced on dev:

    • Per-target context windows: combo rows in the generated Codex catalog are managed output and are regenerated by design. Provider modelContextWindows in ~/.opencodex/config.json is read during sync, and no sync writer that changes it was found.
    • Combo defaultEffort in ~/.opencodex/config.json: sync only reads it (src/codex/catalog/aggregation.ts), and no writer that reverts it was found.

    If either of the last two still happens on a current version, please attach the redacted before/after of the exact key path, the command order, and whether another writer (the dashboard, a second host) was running. This stays open for the maintainer decision on legacy marker-only ownership.

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

    bugSomething isn't workingcliCLI, config inject, packaging flagsplatformOS/service/tray/ACL (Windows-heavy, not Windows-only)

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions