Repository navigation
Description
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/messageswork GET /v1/modelsreturns401 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
- Agent Plan Anthropic path:
- Provider config shape:
adapter: anthropic, key auth
Current behaviour
- Provider key is valid for inference:
POST <baseUrl>/v1/messages→200, model responds correctly
- Same key fails model discovery:
GET <baseUrl>/v1/models?limit=1000→401 AuthenticationError
- service.log shows something like:
Provider model discovery for "<name>" failed with HTTP 401 [urlClass=provider-models, fallback=configured].
- If no custom model has been registered yet, the provider vanishes from:
- OpenCodex Models tab
- Claude model discovery
- 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:
- Keep the provider visible even if
/v1/modelsfails. - 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
- Surface discovery failure clearly (
401, discovery failed badge / log-backed reason), instead of silent disappearance. - 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 worksWhy 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:
- Treat configured
defaultModel/customModelsas durable catalog entries independent of discovery success. - Add an explicit provider/model field such as
manualModelsor strengthen existing custom-model support so discovery failure never removes configured models. - In dashboard / model interface:
- show provider even when discovery fails
- allow adding model ids manually
- badge the provider with
discovery failed (401)or similar
- Keep discovery as best-effort enrichment, not a hard gate for provider visibility.
Additional context
- Related prior report on Responses path construction for Agent Plan: [Bug]: Volcengine Ark Agent Plan Responses URL incorrectly appends /v1 #289
- Related anthropic streaming issue already fixed on
dev: [Bug]: anthropic adapter returns empty content (adapter_eof / 0 tokens) for streaming requests against upstreams that emit reasoning blocks (Kimi k3) #312 - This report is specifically about model discovery + manual model specification, not inference correctness after a model is registered.
- No API keys or credentials are included.
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/modelsreturns 401, and manually specifying the model restores usability.
Activity
Ingwannu commentedon Jul 23, 2026
Verified against the current
devtip (92d9a9e2).The reported behavior is real for 2.7.33: a failed live discovery can produce zero model rows even though inference is usable. However, the core recovery path has already been addressed on
devby merged PR #313:+custom-model action backed byPOST /api/custom-models;defaultModelas the fallback when live discovery fails;I re-ran the catalog, empty-provider grouping, and GUI hint tests on the latest
dev; they pass.One part is still not implemented: the UI does not retain and display the specific discovery status/reason such as HTTP 401. It currently shows generic discovery guidance and the detailed status remains in the service log. So the blocking “provider vanishes / no manual entry path” portion is fixed on
dev; a discovery-error badge would be a separate observability enhancement.Merge pull request #358 from lidge-jun/codex/260724-ux-discovery
Merge pull request lidge-jun#358 from lidge-jun/codex/260724-ux-disco…