Switching model_provider hides existing local sessions from resume/fork/history

Resolved 💬 8 comments Opened Mar 23, 2026 by Dailin521 Closed Mar 31, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor) responded on this thread — see the highlighted reply below.

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 --last
  • codex 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_provider for 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.rs
  • codex-rs/exec/src/lib.rs
  • codex-rs/tui/src/resume_picker.rs
  • codex-rs/tui_app_server/src/lib.rs
  • codex-rs/tui_app_server/src/resume_picker.rs
  • codex-rs/app-server/src/codex_message_processor.rs

There is also an app-server semantic wrinkle:

  • model_providers: None is 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

  1. Start with built-in OpenAI auth and create a few local sessions.
  2. Switch config.toml to a custom model_provider.
  3. Try any of the following:
  • codex resume --last
  • codex fork --last
  • /resume inside TUI
  • open Codex Desktop and browse local history
  1. Observe that previously saved local sessions are missing from discovery/history, even though they still exist under ~/.codex/sessions and in state_5.sqlite.
  2. 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 --last should 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:

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.

View original on GitHub ↗

8 Comments

github-actions[bot] contributor · 3 months ago

Potential duplicates detected. Please review them and close your issue if it is a duplicate.

  • #15219

Powered by Codex Action

Dailin521 · 3 months ago

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:

  • #15219: the thread is already visible/selectable, but thread/resume restores the wrong model_provider, so the resumed conversation is sent to the wrong backend and fails.
  • #15494: switching model_provider hides existing local sessions from discovery in the first place. The rollout files / SQLite rows still exist, but they disappear from resume --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:

patrick-fu · 3 months ago

Is 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 --all

Dailin521 · 3 months ago
Is 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 --all这个问题有临时的解决方案吗?切换到新的模型提供商后,即使使用 --all 参数,我也无法找到历史会话了 codex resume --all

Check this out: https://github.com/Dailin521/codex-provider-sync — might help.

daquexian · 3 months ago

use codexresume as a drop-in replacement for codex resume to fix this problem:

cargo install codexresume

cat >> ~/.bashrc << 'EOF'
codex() {
  if [ "$1" = "resume" ]; then shift; command codexresume "$@"; else command codex "$@"; fi
}
EOF

source ~/.bashrc
JaysonGeng · 3 months ago

I prepared and validated a patch on my fork using the caller-side approach described in this issue.

Branch / compare:

What it changes:

  • makes local CLI resume --last / fork --last discovery search across local providers
  • updates app-server/TUI latest-session lookup and /resume picker to use an explicit empty provider list for "all providers"
  • preserves provider identity on stored threads; this only changes discovery defaults
  • adds regression coverage for empty-provider-filter semantics plus cross-provider lookup behavior in exec/tui/app-server

Validation I ran locally:

  • cargo check -p codex-exec -p codex-tui -p codex-app-server --tests
  • targeted regression tests for exec, tui, resume picker, and app-server thread list
  • just fmt
  • just fix -p codex-exec
  • just fix -p codex-app-server
  • just fix -p codex-tui
  • git diff --check

One local limitation: just argument-comment-lint did not run in this environment because bazel is not installed and the invoked recipe could not find ./tools/argument-comment-lint/list-bazel-targets.sh from 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.

etraut-openai contributor · 3 months ago

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 --all if you understand the risks and want to attempt to resume a session with a different model provider.

TyronMYoung11 · 1 month ago

@Dailin521 It Looks great in first view, but as is not English, is not usable.