Switching model_provider hides existing local sessions from resume/fork/history
Summary
Switching model_provider currently hides existing local sessions from multiple Codex surfaces, even though the rollout files and SQLite rows are still present.
Affected flows:
codex resume --lastcodex fork --last- TUI
/resume/ fork picker - Codex Desktop local history picker and latest-session lookup
This makes local history appear to "disappear" whenever users switch between the built-in OpenAI provider and a custom provider/profile.
Why this matters
A common setup is:
- use built-in OpenAI auth for normal
codex - switch to a custom
model_providerfor a proxy / Azure / gateway / custom backend - switch back later
Today, the session data is still on disk, but discovery defaults to the active provider, so prior local sessions are no longer visible from normal resume/history flows.
That pushes users toward risky local workarounds such as rewriting model_provider in rollout files / SQLite just to make history visible again.
Root cause
The problem is in the caller-side discovery defaults, not in storage.
The core listing APIs already support optional provider filtering, but several callers force the current provider by default:
codex-rs/tui/src/lib.rscodex-rs/exec/src/lib.rscodex-rs/tui/src/resume_picker.rscodex-rs/tui_app_server/src/lib.rscodex-rs/tui_app_server/src/resume_picker.rscodex-rs/app-server/src/codex_message_processor.rs
There is also an app-server semantic wrinkle:
model_providers: Noneis interpreted as "use the current provider"- an explicit empty list can be treated as "all providers"
So even when the UI wants "show all local sessions", it can still accidentally fall back to the active provider.
Reproduction
- Start with built-in OpenAI auth and create a few local sessions.
- Switch
config.tomlto a custommodel_provider. - Try any of the following:
codex resume --lastcodex fork --last/resumeinside TUI- open Codex Desktop and browse local history
- Observe that previously saved local sessions are missing from discovery/history, even though they still exist under
~/.codex/sessionsand instate_5.sqlite. - Switch the provider back and the sessions reappear.
Expected behavior
Local session discovery should default to "all local providers" unless the user explicitly asks to filter by provider.
Provider identity should still be preserved per thread for actual resume/fork execution. This issue is about history visibility and local discovery, not about erasing provider metadata.
Proposed fix
Change the default local discovery behavior to be cross-provider:
resume --last/fork --lastshould look across local providers- local TUI and Desktop history pickers should list local CLI / VS Code sessions across providers
- app-server clients should use an explicit empty provider list to mean "all providers" rather than relying on
None
This seems materially safer and smaller than introducing a built-in sync/migration command that rewrites rollout metadata and SQLite state.
Why not a built-in sync command?
I initially considered proposing an official sync command that rewrites local model_provider metadata so history becomes visible again.
That approach seems much more invasive because it would need to handle:
- rollout file rewrites
- SQLite updates
- locked files
- backup / rollback semantics
- future schema / migration compatibility
The visibility problem appears solvable without mutating history at all: make discovery cross-provider by default.
Prepared implementation
I already prepared a patch on my fork that takes this approach:
- branch:
codex/cross-provider-session-discovery - commit:
0592e899c6457207b18c4e2ebd14fc73f181ffd1 - fork branch URL: https://github.com/Dailin521/codex/tree/codex/cross-provider-session-discovery
It updates CLI, TUI, Desktop app lookup/picker paths, and adds a regression test for the empty-provider-filter behavior.
I have not opened a PR because docs/contributing.md says external PRs are invitation-only and uninvited PRs will be closed. If this direction aligns with the intended product behavior, I can open a PR immediately after a maintainer invitation.
Related
Related but distinct from:
- #15219
That issue is about resuming a thread on the wrong provider. This one is about local history/session discovery being hidden by the active-provider default.
8 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Thanks. I reviewed #15219 and I do not think this one is a pure duplicate.
The two issues are related, but they fail at different stages:
thread/resumerestores the wrongmodel_provider, so the resumed conversation is sent to the wrong backend and fails.model_providerhides existing local sessions from discovery in the first place. The rollout files / SQLite rows still exist, but they disappear fromresume --last,fork --last, TUI/resume, and Desktop local history because discovery defaults to the active provider.So #15219 is a resume-routing problem, while this issue is a local history discovery/filtering problem.
They may both need fixes for cross-provider workflows, but fixing only #15219 would still leave the visibility problem: users still would not see many existing local sessions after switching providers.
If maintainers prefer to track both under a single issue, that is fine, but I wanted to call out that this report covers a distinct discovery-path bug.
I also have a patch prepared for the discovery side if that direction is useful:
codex/cross-provider-session-discovery0592e899c6457207b18c4e2ebd14fc73f181ffd1Is there a temporary workaround for this issue? After switching to a new model provider, I can no longer find the historical sessions, even with the --all parameter
codex resume --allCheck this out: https://github.com/Dailin521/codex-provider-sync — might help.
use codexresume as a drop-in replacement for
codex resumeto fix this problem:I prepared and validated a patch on my fork using the caller-side approach described in this issue.
Branch / compare:
fix/cross-provider-session-discovery92adb2fe9bd18ef33f768a9d0bb3343f579bc4e0What it changes:
resume --last/fork --lastdiscovery search across local providers/resumepicker to use an explicit empty provider list for "all providers"Validation I ran locally:
cargo check -p codex-exec -p codex-tui -p codex-app-server --testsjust fmtjust fix -p codex-execjust fix -p codex-app-serverjust fix -p codex-tuigit diff --checkOne local limitation:
just argument-comment-lintdid not run in this environment becausebazelis not installed and the invoked recipe could not find./tools/argument-comment-lint/list-bazel-targets.shfrom the current working directory.Since external PRs are invitation-only per
docs/contributing.md, I have not opened a PR. If this direction looks right, I can open one after maintainer invitation, or a maintainer can cherry-pick from the branch above.The current behavior is by design. Switching between model providers for the same session is not recommended and can lead to bad behaviors. Since this is a major foot-gun, it's not a use case we want to enable through a happy path. You can use
codex resume --allif you understand the risks and want to attempt to resume a session with a different model provider.@Dailin521 It Looks great in first view, but as is not English, is not usable.