Summary
I hit two related issues while testing the bundled Codex provider / app-server path in OpenClaw 2026.4.10 / source checkout 850182b502ccd35caf52d6313113e03fc5521d99.
- A stale
serviceTier: "priority" value can still make it through the OpenClaw Codex bridge, even though the Codex app-server only accepts "fast" | "flex".
- Gateway startup warmup can emit a false warning for
codex/gpt-5.4 because it only uses static resolveModel(...) and does not fall back to resolveModelAsync(...).
User-visible symptoms
1) Codex app-server request failure
The Codex path can fail with errors like:
CodexAppServerRpcError -32600
unknown variant 'priority'
This happens when plugins.entries.codex.config.appServer.serviceTier = "priority" is present.
2) False-negative startup warning
Gateway startup can warn with:
startup model warmup failed for codex/gpt-5.4
Even when the model is actually resolvable through the async path.
Root cause
serviceTier contract drift
The OpenClaw side still models / forwards serviceTier too loosely in a few places:
- plugin schema allows arbitrary string
- runtime config path can forward arbitrary string
- protocol types still used generic
string | null
- tests still contained stale
"priority" fixtures
That lets an invalid value survive until the Codex app-server rejects it.
startup warmup only uses static resolution
prewarmConfiguredPrimaryModel() currently uses static resolveModel(...) only.
For models like codex/gpt-5.4, static resolution can miss even though resolveModelAsync(...) succeeds, which produces a misleading startup warning.
Proposed fix
I validated a minimal source patch locally that does the following:
serviceTier
- narrow Codex
serviceTier handling to "fast" | "flex"
- sanitize invalid values before forwarding requests to the app-server
- tighten the bundled plugin schema enum
- narrow the protocol request types
- update stale test fixtures
- add a regression test proving invalid
serviceTier is dropped without discarding the rest of the config
startup warmup
- keep static
resolveModel(...) first
- if static resolution misses, fall back to
resolveModelAsync(...)
- only warn when both resolution paths fail
- add regression coverage for:
- static miss + async success
- static miss + async miss
Files changed in the local fix
extensions/codex/openclaw.plugin.json
extensions/codex/src/app-server/config.ts
extensions/codex/src/app-server/config.test.ts
extensions/codex/src/app-server/protocol.ts
extensions/codex/src/app-server/run-attempt.test.ts
src/gateway/server-startup-post-attach.ts
src/gateway/server-startup.test.ts
Validation
pnpm exec vitest run \
extensions/codex/src/app-server/config.test.ts \
extensions/codex/src/app-server/run-attempt.test.ts \
src/gateway/server-startup.test.ts
pnpm codex-app-server:protocol:check
Result:
21 passed
- protocol check passed
Local fix artifacts
I have a validated local commit and patch for this:
- local commit:
8953728
- patch available if useful
Notes
The protocol check required a sibling Codex repo checkout for schema verification:
In my environment that was:
/home/bruce/.openclaw/workspace/_vendor/codex
Summary
I hit two related issues while testing the bundled Codex provider / app-server path in OpenClaw
2026.4.10/ source checkout850182b502ccd35caf52d6313113e03fc5521d99.serviceTier: "priority"value can still make it through the OpenClaw Codex bridge, even though the Codex app-server only accepts"fast" | "flex".codex/gpt-5.4because it only uses staticresolveModel(...)and does not fall back toresolveModelAsync(...).User-visible symptoms
1) Codex app-server request failure
The Codex path can fail with errors like:
CodexAppServerRpcError -32600unknown variant 'priority'This happens when
plugins.entries.codex.config.appServer.serviceTier = "priority"is present.2) False-negative startup warning
Gateway startup can warn with:
startup model warmup failed for codex/gpt-5.4Even when the model is actually resolvable through the async path.
Root cause
serviceTier contract drift
The OpenClaw side still models / forwards
serviceTiertoo loosely in a few places:string | null"priority"fixturesThat lets an invalid value survive until the Codex app-server rejects it.
startup warmup only uses static resolution
prewarmConfiguredPrimaryModel()currently uses staticresolveModel(...)only.For models like
codex/gpt-5.4, static resolution can miss even thoughresolveModelAsync(...)succeeds, which produces a misleading startup warning.Proposed fix
I validated a minimal source patch locally that does the following:
serviceTier
serviceTierhandling to"fast" | "flex"serviceTieris dropped without discarding the rest of the configstartup warmup
resolveModel(...)firstresolveModelAsync(...)Files changed in the local fix
extensions/codex/openclaw.plugin.jsonextensions/codex/src/app-server/config.tsextensions/codex/src/app-server/config.test.tsextensions/codex/src/app-server/protocol.tsextensions/codex/src/app-server/run-attempt.test.tssrc/gateway/server-startup-post-attach.tssrc/gateway/server-startup.test.tsValidation
pnpm exec vitest run \ extensions/codex/src/app-server/config.test.ts \ extensions/codex/src/app-server/run-attempt.test.ts \ src/gateway/server-startup.test.ts pnpm codex-app-server:protocol:checkResult:
21 passedLocal fix artifacts
I have a validated local commit and patch for this:
8953728Notes
The protocol check required a sibling Codex repo checkout for schema verification:
../codexIn my environment that was:
/home/bruce/.openclaw/workspace/_vendor/codex