Skip to content

codex: --provider sets a sticky Databricks-Model-Provider-Service header that --model can't clear (breaks switch to managed model service + ug configure) #602

Description

@ali-kero

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

  1. An Azure AI Foundry project with a gpt-5.6-sol deployment.
  2. A UC model-provider-service (OPENAI-typed) linked to that Foundry project — fronting its OpenAI v1 endpoint (…/openai/v1).
  3. A managed FMAPI model service (gateway).
  4. 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:

pong

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:

managed pong

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.)

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions