Skip to content

opencode-route-proxy: 'no endpoint configured' for both GPT providers (openai, openai.alternate) since today's config edits — GPT leaves unreachable through the proxy #3256

Closed

Description

@dezren39

Finding (2026-10-31 evening, from the route_attempt ledger + live probes)

The standalone route proxy (bin/opencode-route-proxy.mjs, :18750 — OpenClaw's door) currently cannot address either GPT provider:

  • Every proxy walk since ~15:29 CDT that reaches a GPT leaf records error_tag=UnknownProvider — "no endpoint configured for provider openai" / "no endpoint configured for provider openai.alternate" (rows 41997/41998 at 18:38:49, 18:39:32 walks, session_id NULL = proxy-direct).
  • The proxy's last successful openai attempt was at ~15:29 CDT (MAX(time_started) for outcome=success); before that it served terra leaves all day.
  • The deployed config's openai and openai.alternate provider blocks are now empty shells — no npm, no options, no baseURL (verified by parsing ~/code/.opencode/opencode.jsonc). OpenCode itself tolerates that (built-in provider defaults), but the proxy's providerBaseURL() resolves endpoints from the config and finds nothing.

This coincides with today's route-config edits (Antigravity removal and related surgery on the same file). The blocks presumably carried an explicit baseURL (historically the codex-proxy door on 127.0.0.1:18744) that the edits dropped. Recent commits touching the file, for the archaeology: ab6df37f4 (Antigravity out of workhorse), 45a1572ef (workhorse primary swaps to Codex Terra), c1af58e34, 90b6d92d5 — all 2026-10-31.

This is distinct from #3216

#3216 is the OpenCode-internal routing failure: fleet sessions reach the real API and get 401 "Missing scopes: api.responses.write" — an OAuth scope/role defect on the GPT credentials, quota-independent. This issue is the standalone proxy never reaching the API at all. Both must be fixed before a GPT leaf can serve through the proxy; fixing this one alone still leaves #3216's 401 behind it.

Ask

Restore the proxy's ability to address the two GPT providers — either:

  1. put the explicit endpoint back in the two provider blocks in the canonical config (confirm the pre-edit value from the config's git history), or
  2. teach providerBaseURL() the built-in defaults for these providers so an empty block is not a dead leaf.

And note the general hazard this exposes: the proxy and OpenCode read the same config file with different tolerance for empty provider blocks, so a config edit that is safe for OpenCode can silently kill leaves for the proxy. The route validation sweeps should cover the proxy's view of the config, not only OpenCode's.

Acceptance criteria

  • The standalone route proxy can address both GPT providers again: a proxy walk reaching an openai or openai.alternate leaf no longer records error_tag=UnknownProvider / "no endpoint configured".
  • The chosen resolution is recorded on this issue: explicit endpoint restored in the two provider blocks (value confirmed from the config's git history), or providerBaseURL() taught the built-in defaults so an empty provider block is not a dead leaf.
  • Route validation covers the proxy's view of the canonical config (not only OpenCode's), so a config edit that empties a provider block is caught before it silently kills proxy leaves.
  • Verified against the route_attempt ledger / a live proxy probe after the fix (note: Fleet workhorse legs failing fleet-wide: provider.auth 401 'Missing scopes: api.responses.write' (15:40 wave 9/9 roots failed) #3216's 401 may still stand behind this — it is a separate defect).

Activity

  1. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    priority/highImportant and time-sensitive
    effort/sSmall: expected under 2 hours of work
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Nov 1, 2026
  2. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    Intake review

    Related: #3216 (the OpenCode-internal 401 scope defect behind this one — distinct, both must be fixed), #3228 (same app/opencode-route-proxy surface, filed the same evening).

    Notes: Evidence is ledger-grade: last successful openai proxy attempt ~15:29 CDT 2026-10-31, every later GPT-leaf walk records UnknownProvider, and the deployed config's two GPT provider blocks are verified empty shells. No merged PR references this issue (checked at intake; the one search hit, PR #2661, is an unrelated mcpx generator PR whose text contains the number).

    Risks: GPT leaves are unreachable through the proxy until this lands — proxy-direct consumers (OpenClaw's door) have no GPT fallback. The config-archaeology option touches the canonical config, so the pre-edit endpoint value must come from git history, not memory.

    Suggested approach: Prefer option 2 (teach providerBaseURL() the built-in defaults) if it matches the proxy's design — it removes the whole class — otherwise restore the explicit endpoints from history; either way add the proxy-view validation in the acceptance criteria.

    — fleet monitor intake, 2026-10-31 fleet-monitor run (19:12 CDT)

  3. added 2 commits that reference this issue on Nov 1, 2026
  4. dezren39 commented on Nov 1, 2026

    @dezren39
    MemberAuthor

    Resolution recorded (option 2, via PR #3830, merged 064ce9e):

    • Chosen resolution: providerBaseURL()'s provider resolution was taught the built-in defaults — no config endpoints were restored or changed. BUILTIN_PROVIDERS in bin/opencode-route-proxy.mjs is now a defaults table merged under each config provider block, so an empty-shell block is not a dead leaf. Defaults and sources (fork developing-today/opencode, packages/ai): openai https://api.openai.com/v1 (src/protocols/openai-chat.ts DEFAULT_BASE_URL); deepseek https://api.deepseek.com/v1; groq https://api.groq.com/openai/v1; openrouter https://openrouter.ai/api/v1; meta https://api.meta.ai/v1 (src/providers/<id>.ts baseURL constants). openai.alternate inherits openai's default via its instanceOf chain. Companion fix: credentialKey now also reads the OAuth {access} credential shape the GPT plan providers store (previously only {key}, which would have left GPT leaves dying locally with "no credential").
    • Same PR, the blocking grammar gap: the proxy now expands experimental.provider_routes groups (fork PR impl(aggregator): make / the stack front door - overview of all projects, attention, health, quotas (board moves to /board) #1134 semantics — ordered/round-robin/weighted, weights keyed by member provider id; concrete providers win a reference; catalog-missing members skipped). Without this, post-collapse walks never reached a GPT leaf at all: the ledger recorded the group id openai-plan as a leaf with UnknownProvider (e.g. row 64537).
    • Validation (AC3): no separate route-validation script exists for the proxy's view; the proxy test suite is that surface and now covers both hazards (bin/opencode-route-proxy.test.mjs, 16/16 pass: group expansion ordered/round-robin/weighted/member-skip + empty-shell openai default resolution).
    • Live verification: fixed proxy on scratch port :18798 against the deployed config (production :18750 untouched) — terra-plan walk recorded rows 67558 (openai.alternate, Authentication, HTTP 401) and 67559 (openai, Authentication, HTTP 401); luna-plan walk recorded rows 67560/67561 (same, gpt-6-luna). The 401 Invalid authentication is api.openai.com's real response to the stored ChatGPT OAuth token; no UnknownProvider remains. As this issue notes, Fleet workhorse legs failing fleet-wide: provider.auth 401 'Missing scopes: api.responses.write' (15:40 wave 9/9 roots failed) #3216's credential-scope defect still stands behind this — that is the remaining blocker for a GPT leaf actually serving through the proxy, and it is a separate defect.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/opencode-route-proxybin/opencode-route-proxy.mjs fleet proxyeffort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)meta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/highImportant and time-sensitivestatus/needs-triageNot yet triaged; needs a first look

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions