---
title: "Advanced Codex pitfalls"
description: "Launch Codex with native Fast and Ultra, keep ChatGPT login with a model provider, and understand compaction, WebSocket, and history."
version: "en"
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.ochub.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Advanced Codex pitfalls

Codex account state, model traffic, and chat history are related but separate.
Most mysterious 401s, compaction failures, and “missing” chats come from
treating them as one thing.

## Start with the right mental model

| Name | Stored in | What it actually does |
| --- | --- | --- |
| OcHub connection ID | OcHub database | Identifies one connection card; it may remain a UUID |
| Codex Provider ID | `model_provider` in `config.toml` | Selects `[model_providers.<id>]` and identifies the Codex history bucket |
| Codex provider name | `[model_providers.<id>].name` | Display and capability-compatibility field; not the history bucket |
| ChatGPT login | `auth.json` or OS credential store | Stores and refreshes ChatGPT credentials |
| Model-provider credential | Active provider authentication fields | Authenticates model requests to a third party or the local OcHub gateway |

Renaming an OcHub card does not migrate chats. Changing `model_provider` can
move new chats to a different bucket. OcHub separates its internal UUID from
the Codex Provider ID; new model-provider connections default to stable
`custom`, and you can choose an explicit value such as `company_proxy`.

> **Treat Provider ID as stable data, not a label**
>
> Use a short, stable value without spaces. Changing an endpoint, model, key, or
> card name normally should not change it. When a legacy connection used its
> UUID as the Provider ID, edit and save it in OcHub; OcHub backs up and migrates
> matching JSONL session metadata and the SQLite thread index.

## Keep ChatGPT login while using a model provider

Use this mode when you still need ChatGPT account state but want model
inference to go through a third-party Responses API or an OcHub model provider.

1. **Sign in to ChatGPT first.** Verify that the official Codex connection works
   alone. Credentials may live in `~/.codex/auth.json` or the OS keychain.

2. **Save the signed-in state as the connection version.** While the official
   connection is current, switch away and choose **Save as new version** when
   OcHub shows the `auth.json` and `config.toml` diff.

3. **Add a Codex connection and select Model provider.** Choose an existing
   provider and the client-facing model.

4. **Set a stable Provider ID.** Use a value such as `company_proxy`. It is the
   history bucket, not the internal OcHub connection ID.

5. **Choose ChatGPT login + third-party API.** OcHub includes the login material
   in this connection version and issues a separate client key for its local
   gateway.

6. **Review the preview.** `model_provider` should contain the stable ID;
   `base_url` should point to the local OcHub gateway; the provider should keep
   both the OpenAI-login requirement and the gateway bearer.

7. **Save, switch, and restart Codex.** Send one short request and confirm the
   `gateway` data source under Usage → Request logs.

A generated configuration looks like this. OcHub generates the key; do not
copy it manually to unrelated machines:

```toml
model_provider = "company_proxy"

[model_providers.company_proxy]
name = "Company Proxy"
base_url = "http://127.0.0.1:4180/v1"
wire_api = "responses"
requires_openai_auth = true
experimental_bearer_token = "rd-..."
```

There are two independent authentication chains:

- Codex owns the ChatGPT login cache.
- Model requests use `rd-...` to enter the OcHub gateway; the gateway then uses
  the model provider's upstream credential.

Keeping `auth.json` does not make a third-party API accept ChatGPT OAuth.
Having only the gateway key does not mean Codex is signed in to ChatGPT.

## Launch Codex with native Fast and Ultra

On macOS, open the local **Codex** app page in OcHub and click **Launch Codex**.
OcHub starts a separate desktop instance whose native model picker can expose
Fast and Ultra for compatible models. This is useful when inference is routed
through a custom model provider and the normal account entitlement check would
otherwise hide or clear those choices.

The launcher performs an in-memory JavaScript injection. It opens a
loopback-only Chrome DevTools Protocol endpoint, attaches to each renderer
before its first application script runs, and intercepts
`app-initial-*.js`. The patch removes the native picker's ChatGPT-account gates
for Fast and Ultra and prevents Codex from clearing the selected Fast service
tier before `thread/start` or `turn/start`. It keeps Codex's own picker, React
components, setting storage, and request format. The installed application is
not modified or re-signed.

1. **Configure and switch the Codex connection.** Select a direct connection or
   model provider whose client-facing model is one of the supported exact model
   IDs below.

2. **Open the local Codex page.** The launcher is intentionally unavailable for
   remote nodes and non-macOS builds.

3. **Click Launch Codex.** OcHub finds `Codex.app` or `ChatGPT.app` in
   `/Applications` or `~/Applications`, starts a separate instance, injects the
   first renderer document, and then reports success.

4. **Use the native picker beneath the composer.** Choose the model, reasoning
   effort, and Fast mode in Codex itself.

5. **Send a short request and inspect Usage → Request logs.** Confirm the model
   and upstream accepted the selected mode before using it for important work.

Current generated-catalog capabilities are exact-match only:

| Model ID | Fast | Max | Ultra |
| --- | --- | --- | --- |
| `gpt-5.6-sol` | Yes | Yes | Yes |
| `gpt-5.6-terra` | Yes | Yes | Yes |
| `gpt-5.6-luna` | Yes | Yes | No |

Unknown or similarly named third-party models do not inherit these capabilities.
An exact model entry already supplied by Codex keeps its own capability metadata.

> **Unlocking the picker does not add an upstream capability**
>
> For a custom provider, Fast is sent through Codex's priority service tier and
> Ultra is a reasoning effort that can use subagents. The relay and final model
> must implement the requested behavior. An upstream may ignore the value, reject
> the request, bill it differently, or run it at standard speed. ChatGPT credit
> Fast mode and API Priority processing are separate billing paths.

The injection lasts only for the instance launched by OcHub. Keep OcHub running
so newly created renderer documents can also be patched, and launch through
OcHub again after quitting Codex. The debugging listener is bound to
`127.0.0.1`; OcHub rejects non-loopback targets.

The patch deliberately fails closed when a Codex update changes the expected
renderer gates. If OcHub reports that injection failed, quit all Codex or
ChatGPT app windows, install a newer OcHub build if available, and launch again.
Do not repeatedly open the failed instance from the Dock, because that bypasses
the OcHub launcher.

## What compaction actually compacts

Long chats have two different kinds of state:

- **Local transcript:** retained on disk for `/resume`, session lists, and
  inspection.
- **Active context:** history sent with the next model request, limited by the
  model context window.

`/compact` compacts active context. Codex replaces older turns with a concise
summary so later requests retain key decisions without unbounded context
growth. It is not the same as deleting the local transcript. Codex may also
compact automatically at its model default; advanced users can override the
trigger with `model_auto_compact_token_limit`.

## What remote compaction means

Ordinary compaction can summarize on the client. Remote compaction delegates a
Responses-specific compaction request to an upstream that implements that
semantics. In the current OcHub implementation, such requests contain a
Responses `compaction_trigger`; there is no faithful Chat Completions or
Anthropic Messages equivalent.

OcHub therefore offers remote compaction only when the selected model provider
has at least one native Responses upstream:

1. Enable a Responses interface on the model provider.
2. Edit the Codex connection and select that provider.
3. Enable **Remote compaction** in the Provider section.
4. Confirm that the preview writes the provider name as exactly `OpenAI`.
5. Restart Codex and test `/compact` in a long chat.

Writing the provider name as `OpenAI` is a current Codex/OcHub capability
compatibility rule. Do not confuse it with `model_provider = "openai"`.
The former names your custom provider; the latter selects Codex's reserved
built-in OpenAI provider and cannot define your relay.

> **OpenAI-compatible does not imply remote compaction**
>
> Many services implement ordinary `/v1/responses` generation but do not
> recognize compaction input. Disable remote compaction if you see HTTP 400,
> unknown input types, or interrupted chats after compaction. OcHub can convert
> ordinary requests for a Chat-only upstream, but it cannot convert remote
> compaction.

## What Responses WebSocket means

`supports_websockets = true` tells Codex that this model provider supports the
Responses API WebSocket transport. A capable provider can then carry Responses
events over a persistent bidirectional connection instead of opening a normal
HTTP/SSE request each time.

Two unrelated WebSocket features are easy to confuse:

| WebSocket | Connects | OcHub/Codex setting |
| --- | --- | --- |
| Responses WebSocket | Codex model client ↔ model provider | `supports_websockets = true` |
| app-server WebSocket | External client ↔ `codex app-server` | `codex --remote` / `app-server --listen` |

OcHub configures the first. It does not turn Codex CLI into a remote app server.

## When to enable WebSocket

Enable it only when all of these are true:

- The upstream explicitly supports Responses WebSocket, not only HTTP streaming.
- The Responses interface in the model provider has WebSocket enabled.
- Network proxies, TLS termination, and corporate CAs allow `wss://` handshakes
  and long-lived connections.
- An ordinary Responses request already succeeds.

After enabling WebSocket in the model-provider editor, OcHub projects the
capability into the Codex connection. Check the `config.toml` preview:

```toml
[model_providers.company_proxy]
wire_api = "responses"
supports_websockets = true
```

WebSocket can reduce repeated connection overhead and fit continuous event
streams, but it does not guarantee lower latency for every upstream. Disable it
when handshakes fail, connections churn, or a corporate proxy supports only
ordinary HTTPS. It cannot fix a wrong model, credential, or Base URL.

## Where chats are stored

Official Codex behavior keeps resumable session transcripts locally. Current
versions typically use these locations under `$CODEX_HOME` (default
`~/.codex`):

- `sessions/`: rollout JSONL for active sessions.
- `archived_sessions/`: archived but restorable sessions.
- `state_5.sqlite`: thread lists, indexes, and provider-bucket state.

These filenames are current implementation details and may change in later
Codex releases. Prefer `/resume`, `/archive`, `codex unarchive`, and OcHub
session management over bulk-editing files while Codex is running.

`auth.json` is not chat history. It contains sensitive login material and
should be protected like a password: never commit it, paste it into tickets,
or share it in public chat.

## Why Provider ID changes history

Codex records `model_provider` in session metadata and its thread index. This
distinguishes the built-in `openai`, shared `custom`, and other providers, but
it also means a Provider ID change changes the session bucket.

Practical rules:

- Changing only the upstream URL, model, or key: keep the Provider ID.
- Sharing history across third-party connections: give them the same stable ID,
  such as `custom`.
- Isolating team and personal history: use distinct IDs such as `team_proxy`
  and `personal_proxy`.
- Replacing a legacy UUID ID: quit Codex and save the new ID through OcHub so
  it can back up and migrate JSONL plus SQLite state.
- `/archive` retains the session locally; `/delete` permanently deletes the
  current session and spawned descendant sessions.

## A reliable troubleshooting order

1. **Login layer:** Does Codex still show a signed-in account? Is the credential
   in a file or keychain?
2. **Provider layer:** Does `model_provider` point to an existing
   `[model_providers.<id>]`?
3. **Gateway layer:** Is the Base URL local to OcHub, and was the `rd-...` key
   issued for this connection?
4. **Ordinary request:** Disable remote compaction and WebSocket, then verify
   one normal Responses request.
5. **WebSocket:** Enable it only after confirming upstream and network support.
6. **Compaction:** Enable remote compaction last and test `/compact` separately.
7. **History:** If `/resume` changes, verify `CODEX_HOME` and Provider ID before
   deleting anything.

## Official references and implementation boundaries

- OpenAI's [Codex configuration reference](https://learn.chatgpt.com/docs/config-file/config-reference)
  defines `model_provider`, `requires_openai_auth`, `supports_websockets`, and
  auto-compaction thresholds.
- OpenAI's [Codex authentication and sessions](https://learn.chatgpt.com/docs/auth)
  explains login caching and credential storage.
- OpenAI's [Codex CLI commands](https://learn.chatgpt.com/docs/developer-commands.md?surface=cli)
  documents `/compact`, `/resume`, `/archive`, and `/delete`.
- OpenAI's [Codex model selection](https://learn.chatgpt.com/docs/models.md)
  describes model, reasoning, Max, and Ultra controls.
- OpenAI's [Codex speed guide](https://learn.chatgpt.com/docs/agent-configuration/speed.md)
  distinguishes ChatGPT Fast mode from API Priority processing.
- Provider-name remote-compaction detection, Responses-only routing guards,
  native-picker injection, UUID history migration, and exact scanned file paths
  are OcHub compatibility behavior for current Codex versions, not a permanent
  OpenAI protocol promise.

Source: https://docs.ochub.org/codex/advanced/index.mdx
