Codex Desktop hides local history for custom Azure model provider after restart (e.g. corporate API key)
What version of the Codex App are you using (From “About Codex” dialog)?
26.422.71525
What subscription do you have?
personal + corporate AzureOpenAI API key
What platform is your computer?
26.0 (25A8353)
What issue are you seeing?
- Optional provider filter; when set, only sessions recorded under these
- providers are returned. When present but empty, includes all providers.
*/
modelProviders?: Array<string> | null
Local testing showed:
- `thread/list` with `modelProviders: []` returned both `openai` and `azure` threads.
- `thread/list` with `modelProviders: null` could behave like a current-provider filter.
- The Desktop UI bundle contains `thread/list` calls with `modelProviders:null`.
This suggests the Desktop UI may be listing recent threads using provider filter semantics that exclude custom providers after restart, or it may be applying a UI-side provider filter that does not include custom providers.
## Additional Observations
`thread/list` without a `cwd` filter and with `modelProviders: []` returned mixed providers, including both:
```text
openai | vscode | /Users/uberkinder/projects/bp/Hercules
azure | vscode | /Users/uberkinder/projects/bp/Hercules
azure | vscode | /Users/uberkinder/projects/bp/Hercules
azure | vscode | /Users/uberkinder/projects/bp/Hercules
thread/list with a cwd filter for Hercules and modelProviders: [] also returned both openai and azure threads in that repo.
This further supports that the underlying app-server can return the data needed by the UI.
Failed Workarounds
1. Duplicating Provider Definition Into Repo Config
Duplicating [model_providers.azure] into the repo-local .codex/config.toml did not fix Desktop history.
CLI still worked and reported:
provider: azure
But the Desktop GUI still did not show corporate/Azure chats after restart.
2. Trying To Override Built-In openai Provider
Attempting to configure built-in openai to point at Azure did not work. Codex still sent requests to:
https://api.openai.com/v1/responses
This is not a viable workaround.
3. Patching app.asar
Two local experiments were attempted only to test the provider-filter hypothesis. Both are not viable and should not be used as a workaround.
First attempt:
- Extracted
app.asar. - Replaced
modelProviders:nullin JS. - Repacked
app.asar. - Result: Codex Desktop crashed at startup with
EXC_BREAKPOINT (SIGTRAP). - Likely cause: repacking lost original
app.asar.unpackedmetadata for native modules.
Second attempt:
- Performed an in-place byte-preserving edit:
``js``
modelProviders:null
to:
``js``
modelProviders:([])
- Same byte length.
- No extract/repack.
- Updated affected asar integrity hashes in the header.
- Tested successfully on a
/tmpcopy with@electron/asar list. - Result on the real installed app: Codex Desktop still crashed at startup with
EXC_BREAKPOINT (SIGTRAP). - Likely cause: the installed app cannot tolerate mutation of
Resources/app.asar, probably due to macOS/Electron code signing or resource seal validation.
Relevant crash reports:
/Users/uberkinder/Library/Logs/DiagnosticReports/Codex-2026-04-29-143709.ips
/Users/uberkinder/Library/Logs/DiagnosticReports/Codex-2026-04-29-143726.ips
Resources/app.asar is listed in:
/Applications/Codex.app/Contents/_CodeSignature/CodeResources
So mutating the installed app bundle is not a practical workaround.
Impact
This makes corporate/custom-provider usage unsafe and confusing:
- Work is not lost, but appears lost in the GUI.
- Users cannot reliably reopen or continue corporate Azure chats from Desktop history.
- Personal/default OpenAI history works, making the issue look provider-specific.
- The intended setup of “corporate provider for one repo, personal provider elsewhere” becomes hard to use in Desktop.
- Users may incorrectly assume their corporate chat history was deleted.
Requested Fix
Please make Codex Desktop recent/history views include custom provider threads correctly.
Specifically:
- Ensure
thread/listcalls intended to include all local threads use the correct provider filter semantics. - Treat
modelProviders: []as “all providers” consistently, per the generated app-server protocol. - Ensure custom providers such as
azureare visible in recent chat history after app restart. - Ensure opening/resuming a custom-provider thread renders existing turns instead of a blank UI.
- Add regression coverage for local custom providers with:
source = "vscode"model_provider != "openai"- repo-scoped config selecting a custom provider
- persisted local rollout JSONL history
Security Notes
- No API key is included in this report.
- The Azure endpoint is redacted.
- Corporate chat content examples are limited to short thread titles/previews.
What steps can reproduce the bug?
Reproduction
- Configure a custom model provider named
azurein~/.codex/config.toml. - Configure one repo with local
.codex/config.tomlselecting:
``toml``
model_provider = "azure"
- Open Codex Desktop in that repo.
- Start one or more chats and verify that turns complete successfully through the Azure provider.
- Restart Codex Desktop.
- Check recent chat history.
- Observe that Azure-provider chats are missing or fail to open correctly, while default
openaichats remain visible.
What is the expected behavior?
Expected Behavior
- Threads created in the Hercules repo with
model_provider = "azure"should appear in Codex Desktop recent chat history. - After restarting Codex Desktop, those Azure threads should still appear.
- Opening an Azure thread should render the existing conversation turns, same as
model_provider = "openai"threads. - Personal/default OpenAI threads from other repositories should continue to appear and open normally.
Actual Behavior
- Azure/provider-specific chats are created and saved successfully.
- They may appear temporarily in the Desktop GUI.
- After restarting Codex Desktop, Azure chats disappear from GUI history or open to a blank screen.
- Non-Azure/default OpenAI chats still appear and open normally.
- The missing Azure chats are not deleted and are not archived.
Additional information
019dd592-b080-7fc1-85d6-bb788ea20b45 | azure | vscode | /Users/uberkinder/projects/bp/Hercules | "ты можешь посмотреть пост..."
019dd59e-26bc-79d1-9c6b-209fc88805e6 | azure | vscode | /Users/uberkinder/projects/bp/Hercules | "открой в линеар кейс с Photon"
019dd399-904a-72a3-adcc-720754426b9f | azure | vscode | /Users/uberkinder/projects/bp/Hercules | "можешь в тимс ходить?"
These rows are present in:
/Users/uberkinder/.codex/state_5.sqlite
Their rollout JSONL files also exist under:
/Users/uberkinder/.codex/sessions/2026/04/29/
Evidence: Local App-Server Can Read The Threads
Using the local Codex app-server WebSocket API, both thread/list and thread/read can see/read the Azure threads.
Example thread/read for:
019dd592-b080-7fc1-85d6-bb788ea20b45
Returned:
{
"id": "019dd592-b080-7fc1-85d6-bb788ea20b45",
"modelProvider": "azure",
"cwd": "/Users/uberkinder/projects/bp/Hercules",
"source": "vscode",
"turns": 20,
"preview": "ты можешь посмотреть пост который я в Viva Engage закинул"
}
This indicates that the backend/state layer can load the conversation and the data is not lost.
Evidence: Provider Filter Semantics May Be Involved
Generated app-server TypeScript protocol says:
/**
* Optional provider filter; when set, only sessions recorded under these
* providers are returned. When present but empty, includes all providers.
*/
modelProviders?: Array<string> | null
Local testing showed:
thread/listwithmodelProviders: []returned bothopenaiandazurethreads.thread/listwithmodelProviders: nullcould behave like a current-provider filter.- The Desktop UI bundle contains
thread/listcalls withmodelProviders:null.
This suggests the Desktop UI may be listing recent threads using provider filter semantics that exclude custom providers after restart, or it may be applying a UI-side provider filter that does not include custom providers.
Additional Observations
thread/list without a cwd filter and with modelProviders: [] returned mixed providers, including both:
openai | vscode | /Users/uberkinder/projects/bp/Hercules
azure | vscode | /Users/uberkinder/projects/bp/Hercules
azure | vscode | /Users/uberkinder/projects/bp/Hercules
azure | vscode | /Users/uberkinder/projects/bp/Hercules
thread/list with a cwd filter for Hercules and modelProviders: [] also returned both openai and azure threads in that repo.
This further supports that the underlying app-server can return the data needed by the UI.
Failed Workarounds
1. Duplicating Provider Definition Into Repo Config
Duplicating [model_providers.azure] into the repo-local .codex/config.toml did not fix Desktop history.
CLI still worked and reported:
provider: azure
But the Desktop GUI still did not show corporate/Azure chats after restart.
2. Trying To Override Built-In openai Provider
Attempting to configure built-in openai to point at Azure did not work. Codex still sent requests to:
https://api.openai.com/v1/responses
This is not a viable workaround.
3. Patching app.asar
Two local experiments were attempted only to test the provider-filter hypothesis. Both are not viable and should not be used as a workaround.
First attempt:
- Extracted
app.asar. - Replaced
modelProviders:nullin JS. - Repacked
app.asar. - Result: Codex Desktop crashed at startup with
EXC_BREAKPOINT (SIGTRAP). - Likely cause: repacking lost original
app.asar.unpackedmetadata for native modules.
Second attempt:
- Performed an in-place byte-preserving edit:
``js``
modelProviders:null
to:
``js``
modelProviders:([])
- Same byte length.
- No extract/repack.
- Updated affected asar integrity hashes in the header.
- Tested successfully on a
/tmpcopy with@electron/asar list. - Result on the real installed app: Codex Desktop still crashed at startup with
EXC_BREAKPOINT (SIGTRAP). - Likely cause: the installed app cannot tolerate mutation of
Resources/app.asar, probably due to macOS/Electron code signing or resource seal validation.
Relevant crash reports:
/Users/uberkinder/Library/Logs/DiagnosticReports/Codex-2026-04-29-143709.ips
/Users/uberkinder/Library/Logs/DiagnosticReports/Codex-2026-04-29-143726.ips
Resources/app.asar is listed in:
/Applications/Codex.app/Contents/_CodeSignature/CodeResources
So mutating the installed app bundle is not a practical workaround.
Impact
This makes corporate/custom-provider usage unsafe and confusing:
- Work is not lost, but appears lost in the GUI.
- Users cannot reliably reopen or continue corporate Azure chats from Desktop history.
- Personal/default OpenAI history works, making the issue look provider-specific.
- The intended setup of “corporate provider for one repo, personal provider elsewhere” becomes hard to use in Desktop.
- Users may incorrectly assume their corporate chat history was deleted.
6 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
I reviewed the suggested duplicates.
#19088 is the closest match and appears to describe the same user-visible Azure Desktop history symptom.
However, this issue adds narrower evidence that this is not merely "resume across providers":
model_provider = "azure"model_provider = "azure"thread/readcan read the affected Azure threadsthread/listwithmodelProviders: []returns themSo the requested behavior is not to resume an Azure thread through OpenAI or migrate encrypted content across providers. The requested behavior is that Desktop history/listing should show and open persisted threads under their original provider, or at least not hide same-provider Azure threads when the backend can already read them.
This seems distinct from the "by design" cross-provider resume limitation discussed in #19318 / #15494, and closer to a Desktop/app-server discovery/filtering bug.
Reproduced again with a fresh minimal case after filing this issue.
On 2026-04-29 I created a brand-new chat in the same Hercules repo with repo-local
model_provider = "azure". The chat completed successfully and was persisted locally. Then I closed Codex Desktop, reopened it, and the new Azure chat disappeared from GUI history as well.The corresponding local row still exists and is not archived:
Ya this hit me as well after shifting from Azure to chatgpt pro sub. At the time, codex itself was able to patch my session history to switch Azure to openai within each session and was able to get them to show up again(and was able to resume them). Would love to see them implement better handling for these scenarios.
FYI @uberkinder, it is possible to patch the ASAR with the patch you mentioned, you just have to take a few extra steps. Codex figured it out for me, so you could also ask it to do this for you: 😆
Patch the extracted files however needed. For this specific issue:
Repack the ASAR:
Update Electron’s ASAR integrity hash. This must hash the ASAR header string, not the whole file:
If you are making a copy of the app and want it to coexist with the installed one, change only the main bundle
identifier:
Do not rename CFBundleName, and do not rename the helper apps.
Clear quarantine and resign:
Adding another reproduction from Windows with custom OpenAI-compatible providers. This is not Azure-specific.
Environment
WindowsAppsinstallOpenAI.Codex_26.623.19656.0_x64__2p2nqsd0c76g0~/.codex/version.jsonreportslatest_version: 0.141.0[model_providers.*]inconfig.tomlUser-visible behavior
After switching
model_providerbetween custom OpenAI-compatible providers, the Desktop sidebar and thelist_threadstool only show threads for the current provider. Threads from the previous provider appear to be gone, but they are still on disk and can still be read if the thread id is known.Local evidence
The local state DB still contains threads across multiple provider buckets. The exact provider ids are omitted, but a read-only query against
~/.codex/state_5.sqliteshowed non-archived thread records split across several buckets, for example:At the time,
list_threadsreturned only the currently active provider bucket. However, a hidden non-current-provider thread could still be read directly by id through the app thread API, confirming the data is not deleted and the JSONL/session state is still usable.session_index.jsonlalso does not contain a provider/model field, so the provider-specific visibility appears to come from the app-server/thread-listing path rather than from the raw session index.Root-cause hint
This matches the provider filter semantics already discussed above:
In the installed Windows
app.asar, there are 10 occurrences ofmodelProviders:nullin thread-listing paths. The affected bundled files include:Relevant examples include calls for recent threads, archived threads, dynamic
list_threads, thread-id resolution, background thread hydration, and subagent tree lookup. These call sites appear to request all local threads, but passmodelProviders:null; per the generated protocol, the all-provider value should be an empty array (modelProviders: []).Expected fix
For Desktop/sidebar/history calls that are intended to show all local history, please pass an empty provider filter instead of
null, for example:model_providershould remain session metadata for compatibility/resume decisions, but it should not hide local history unless the UI explicitly applies a provider filter.