Skip to content

[Bug]: provider vanishes when /v1/models discovery returns 401; Agent Plan needs manual model specification #329

Description

@lijianmac

Summary

With adapter: anthropic (and similarly other adapters that rely on OpenAI-style model discovery), OpenCodex runs model discovery via:

GET <baseUrl>/v1/models?limit=1000

Some upstreams authorize the API key for inference, but not for the models list endpoint. A concrete case is Volcengine Ark Agent Plan / Coding Plan:

  • inference endpoints such as /v1/messages work
  • GET /v1/models returns 401 AuthenticationError

When discovery fails and no customModels entry exists, the entire provider silently disappears from the Models tab / Claude model discovery. There is no UI path to manually specify a model id, even though the provider is usable after a manual custom-model registration.

Environment

  • opencodex: 2.7.33
  • macOS, Apple Silicon
  • Upstream: Volcengine Ark Agent Plan / Coding Plan
  • Example model: glm-5-2 / glm-5-2-260617
  • Example base URLs:
    • Agent Plan Anthropic path: https://ark.cn-beijing.volces.com/api/plan
    • Coding Plan Anthropic path: https://ark.cn-beijing.volces.com/api/coding
  • Provider config shape: adapter: anthropic, key auth

Current behaviour

  1. Provider key is valid for inference:
    • POST <baseUrl>/v1/messages200, model responds correctly
  2. Same key fails model discovery:
    • GET <baseUrl>/v1/models?limit=1000401 AuthenticationError
  3. service.log shows something like:
    • Provider model discovery for "<name>" failed with HTTP 401 [urlClass=provider-models, fallback=configured].
  4. If no custom model has been registered yet, the provider vanishes from:
    • OpenCodex Models tab
    • Claude model discovery
  5. There is no dashboard / model-list UI affordance to manually enter a known model id as a fallback when discovery fails.

Expected behaviour

When model discovery fails (especially with 401 / permission-limited plan keys), OpenCodex should not hide a still-usable provider.

Specifically:

  1. Keep the provider visible even if /v1/models fails.
  2. Support manual model specification at the model-interface / provider layer (config and preferably dashboard UI), e.g.:
    • default model
    • custom model ids / catalog entries
    • configured fallback models used when discovery fails
  3. Surface discovery failure clearly (401, discovery failed badge / log-backed reason), instead of silent disappearance.
  4. Once a model is manually specified, expose it to Codex / Claude as a normal selectable model.

Workaround found

Manually register the known model via:

POST /api/custom-models

After that, the provider reappears and inference works immediately.

This proves:

  • discovery failure ≠ inference failure
  • Agent Plan can be used successfully once the model id is specified manually
  • the missing piece is a first-class manual model entry path when discovery is unavailable

Minimal redacted reproduction

# 1) Inference works
curl -sS -X POST 'https://ark.cn-beijing.volces.com/api/plan/v1/messages' \
  -H 'x-api-key: <REDACTED>' \
  -H 'anthropic-version: 2023-06-01' \
  -H 'content-type: application/json' \
  -d '{
    "model": "glm-5-2",
    "max_tokens": 32,
    "messages": [{"role":"user","content":"Reply exactly: OK"}]
  }'
# → HTTP 200

# 2) Model list fails with the same key
curl -sS 'https://ark.cn-beijing.volces.com/api/plan/v1/models?limit=1000' \
  -H 'x-api-key: <REDACTED>'
# → HTTP 401 AuthenticationError

# 3) OpenCodex result without customModels:
# provider disappears from Models tab / discovery UI

# 4) After manual custom model registration:
# provider reappears and inference through OpenCodex works

Why this matters for Agent Plan

Volcengine Agent Plan is a practical multi-model coding/plan product. In practice:

  • plan keys may be allowed to call chat/messages endpoints
  • plan keys may not be allowed to list models
  • the usable model ids are still known to the user (e.g. glm-5-2)

So OpenCodex currently creates a false “provider broken” state for a working Agent Plan route. Manual model specification should be a supported primary path, not only a hidden recovery API.

Suggested implementation notes

Possible backward-compatible approaches:

  1. Treat configured defaultModel / customModels as durable catalog entries independent of discovery success.
  2. Add an explicit provider/model field such as manualModels or strengthen existing custom-model support so discovery failure never removes configured models.
  3. In dashboard / model interface:
    • show provider even when discovery fails
    • allow adding model ids manually
    • badge the provider with discovery failed (401) or similar
  4. Keep discovery as best-effort enrichment, not a hard gate for provider visibility.

Additional context

Checks

  • I searched existing provider and compatibility issues.
  • The request and response details were redacted.
  • The expected behaviour is based on concrete reproduction: Agent Plan inference works, /v1/models returns 401, and manually specifying the model restores usability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions