Bug — ucode/ug can't cleanly switch a Codex session between an external provider service and a managed model service
Summary.
After ug codex --provider <model-provider-service>, ug writes the Databricks-Model-Provider-Service header into its Codex config and never removes it.
A later ug codex --model <managed-model-service> run (with no --provider) leaves the stale header in
place, so the request still routes to the external provider and fails with 403 PERMISSION_DENIED — even though the user requested the managed model service.
- Component: ucode / ug —
src/ucode/agents/codex.py
- Version observed:
ucode/0.1.0+101.ge7553f4, codex/0.153.4
- Severity: medium–high — the stale header (1) misroutes managed-service requests to the external provider (403) and (2) makes
ug configure --agent codex fail validation and revert the config. Manual header removal is the only workaround.
- Status: reproduced 2026-09-14 on workspace
fe-sandbox-outcasts-code.
Prerequisites
- An Azure AI Foundry project with a
gpt-5.6-sol deployment.
- A UC model-provider-service (OPENAI-typed) linked to that Foundry project — fronting its OpenAI v1 endpoint (
…/openai/v1).
- A managed FMAPI model service (gateway).
ucode/ug configured for Codex against workspace
Steps to reproduce
1. Route Codex to the external provider — works
ug codex --provider outcasts_code_catalog.ugw_demo.azure_openai \
--workspace https://fe-sandbox-outcasts-code.cloud.databricks.com/ \
--model gpt-5.6-sol -- "say pong"
ucode edits the Codex config files, and Codex answers:
2. Switch to the internal (managed) model service — fails
ug codex --model outcasts_code_catalog.ugw_demo.codex_ugw \
--workspace https://fe-sandbox-outcasts-code.cloud.databricks.com/ \
-- "say managed pong"
Returns 403:
■ unexpected status 403 Forbidden: {"error_code":"PERMISSION_DENIED","message":"Model
'outcasts_code_catalog.ugw_demo.codex_ugw' is not in the allowed models list for
'outcasts_code_catalog.ugw_demo.azure_openai'."}, url:
https://fe-sandbox-outcasts-code.cloud.databricks.com/ai-gateway/codex/v1/responses, request id:
0cff2192-3c94-428c-be43-d74818f11d82
3. Manually remove the stale header — then it works
sudo sed -i '' '/Databricks-Model-Provider-Service/d' /etc/codex/managed_config.toml
sed -i '' '/Databricks-Model-Provider-Service/d' ~/.codex/ucode.config.toml
Retry step 2:
ucode codex --model outcasts_code_catalog.ugw_demo.codex_ugw \
--workspace https://fe-sandbox-outcasts-code.cloud.databricks.com/ \
-- "say managed pong"
Codex answers:
Expected vs actual
- Expected: step 2 routes to the managed model service
codex_ugw and replies managed pong.
- Actual: step 2 still carries
Databricks-Model-Provider-Service: outcasts_code_catalog.ugw_demo.azure_openai
(written in step 1), so the gateway routes to the external provider, which rejects codex_ugw → 403.
Affected files (written by ucode)
~/.codex/ucode.config.toml
/etc/codex/managed_config.toml (machine-wide managed config)
Both retain the stale [model_providers.ucode-databricks.http_headers] entry:
Databricks-Model-Provider-Service = "outcasts_code_catalog.ugw_demo.azure_openai"
Second symptom — the stale header also breaks ug configure --agent codex
The leftover header doesn't only misroute chat requests; it also makes reconfiguration fail. After
a --provider run, with the header still present:
ug configure --agent codex
fails validation and rolls back:
ERROR Codex: codex/v1/models is not enabled for this workspace.
ERROR Codex validation failed — config reverted.
Removing the header (the workaround above) makes ug configure --agent codex succeed again.
Why: configure's Codex validation probes codex/v1/models. With the stale
Databricks-Model-Provider-Service header, that probe is routed to the external model-provider-service
(which doesn't serve the /models listing endpoint), so validation fails and the freshly written config
is reverted — leaving the user unable to reconfigure until the header is manually stripped.
(This path intersects the in-flight AIGTWY-4573 work — #594/#600/#601 touch codex/v1/models and the
model catalog — so the validation-probe behavior is actively changing.)
Bug — ucode/ug can't cleanly switch a Codex session between an external provider service and a managed model service
Summary.
After
ug codex --provider <model-provider-service>, ug writes theDatabricks-Model-Provider-Serviceheader into its Codex config and never removes it.A later
ug codex --model <managed-model-service>run (with no--provider) leaves the stale header inplace, so the request still routes to the external provider and fails with 403 PERMISSION_DENIED — even though the user requested the managed model service.
src/ucode/agents/codex.pyucode/0.1.0+101.ge7553f4,codex/0.153.4ug configure --agent codexfail validation and revert the config. Manual header removal is the only workaround.fe-sandbox-outcasts-code.Prerequisites
gpt-5.6-soldeployment.…/openai/v1).ucode/ugconfigured for Codex against workspaceSteps to reproduce
1. Route Codex to the external provider — works
ug codex --provider outcasts_code_catalog.ugw_demo.azure_openai \ --workspace https://fe-sandbox-outcasts-code.cloud.databricks.com/ \ --model gpt-5.6-sol -- "say pong"ucode edits the Codex config files, and Codex answers:
2. Switch to the internal (managed) model service — fails
ug codex --model outcasts_code_catalog.ugw_demo.codex_ugw \ --workspace https://fe-sandbox-outcasts-code.cloud.databricks.com/ \ -- "say managed pong"Returns 403:
3. Manually remove the stale header — then it works
Retry step 2:
ucode codex --model outcasts_code_catalog.ugw_demo.codex_ugw \ --workspace https://fe-sandbox-outcasts-code.cloud.databricks.com/ \ -- "say managed pong"Codex answers:
Expected vs actual
codex_ugwand repliesmanaged pong.Databricks-Model-Provider-Service: outcasts_code_catalog.ugw_demo.azure_openai(written in step 1), so the gateway routes to the external provider, which rejects
codex_ugw→ 403.Affected files (written by ucode)
~/.codex/ucode.config.toml/etc/codex/managed_config.toml(machine-wide managed config)Both retain the stale
[model_providers.ucode-databricks.http_headers]entry:Second symptom — the stale header also breaks
ug configure --agent codexThe leftover header doesn't only misroute chat requests; it also makes reconfiguration fail. After
a
--providerrun, with the header still present:fails validation and rolls back:
Removing the header (the workaround above) makes
ug configure --agent codexsucceed again.Why:
configure's Codex validation probescodex/v1/models. With the staleDatabricks-Model-Provider-Serviceheader, that probe is routed to the external model-provider-service(which doesn't serve the
/modelslisting endpoint), so validation fails and the freshly written configis reverted — leaving the user unable to reconfigure until the header is manually stripped.
(This path intersects the in-flight AIGTWY-4573 work — #594/#600/#601 touch
codex/v1/modelsand themodel catalog — so the validation-probe behavior is actively changing.)