Skip to content

opencode-route-proxy: opendesign leaves sit in pools but the provider's credential is inactive — walks burn attempts and surface a misleading auth error #3228

Open

Description

@dezren39

Finding (2026-10-31, from the route_attempt ledger in opencode.db)

The opendesign provider has a credential row in the OpenCode credential store, but the row is not active (SELECT integration_id, COUNT(*), SUM(active) FROM credential GROUP BY 1 → opendesign: 1 row, SUM(active) = NULL). The route proxy's credential lookup requires active = 1 (bin/opencode-route-proxy.mjs, credentialKey()), so every pool walk that reaches an opendesign leaf records:

  • provider_id=opendesign, outcome=failure, error_tag=Authentication — "no credential for provider opendesign"

The proxy's own header contract says "disabled providers skipped" — but a provider whose credential is merely inactive is not skipped: it burns one of the walk's MAX_ATTEMPTS with a guaranteed failure, and when it is the last candidate tried, its Authentication error is the one surfaced to the caller. Observed live 2026-10-31 ~16:00 CDT: a workhorse completion walked quota-dead deepseek leaves (opencode-go.personal / opencode-go.lab 429 "Go usage limit exceeded", cline-pass 429 monthly limit), a commandcode timeout, and terminated on the opendesign credential error; OpenClaw's gateway then classified the whole run as an auth failure ("Couldn't sign in to opencode-route. Your saved login looks expired") — a misleading surface for what is a dead-credential leaf inside the pool.

Ask

Pick one, per the owner's intent for this provider:

  1. If opendesign should be usable: activate its credential row (after verifying the stored key is still valid), or
  2. If it should not: mark the provider disabled in the OpenCode config so resolveRoute skips its leaves entirely, or remove the opendesign leaves from the pools that contain them (e.g. the deepseek pool containing opendesign/deepseek-v4.1-flash).

Also worth considering in the proxy: a leaf whose credential lookup comes back empty could be treated as a skip (like a disabled provider) rather than an attempt — the credential store's active flag already carries the intent.

Context

Found while closing out the OpenClaw route-only deploy (#3061): the deploy itself is verified working (gateway up on the new system generation, route-only config live, runs walk workhorse → specialist → speed as configured). The runs currently fail on leaf health — chiefly quota exhaustion across the deepseek doors on 2026-10-31 — of which this inactive-credential leaf is the one permanent, non-quota defect.

Acceptance criteria

  • A pool walk never spends one of its attempts on a provider whose credential row is inactive: inactive-credential providers are skipped like disabled providers (or the credential is activated / the provider disabled, per the owner's recorded intent — see the Ask in the original body).
  • When every candidate in a walk fails, the error surfaced to the caller is not a misleading Authentication error produced by an inactive-credential leaf.
  • A test or probe pins the behaviour: a pool containing an inactive-credential leaf and one healthy leaf completes via the healthy leaf with no attempt recorded against the inactive provider.
  • The chosen resolution (activate / disable / skip-inactive) is recorded on this issue.

Activity

  1. added
    kind/infrastructureInfrastructure / host-portability work
    priority/normalOrdinary priority (the default)
    effort/sSmall: expected under 2 hours of work
    user/reviewNeeds a user-look: Muse reviews first and handles what it can
    meta/enrichedIntake review done: acceptance criteria, links, and normalized labels added
    on Oct 31, 2026
  2. dezren39 commented on Oct 31, 2026

    @dezren39
    MemberAuthor

    Intake review

    Related: #3225 (same app/opencode-route-proxy surface, filed the same evening); the misleading-surface failure was observed live 2026-10-31 ~16:00 CDT per the issue body.

    Notes: The defect is verified in the body with the route_attempt ledger evidence: credentialKey() requires active = 1, but resolveRoute does not skip providers whose only credential is inactive, so the walk burns attempts and can surface the dead leaf's Authentication error as the run's failure. The fix direction (skip-inactive in the walk) is mechanical; the choice among the issue's three options is not — options 1 and 2 change the owner's provider setup.

    Risks: Low code risk for the skip-inactive change. The larger risk is leaving the surfaced-error behaviour as-is: downstream classifiers (OpenClaw gateway in the observed case) read it as an expired login and misdirect recovery.

    Suggested approach: Implement skip-inactive in resolveRoute/credentialKey so the walk treats an inactive credential like a disabled provider, pin it with the acceptance-criteria probe, and record the owner's intent for opendesign itself under user/review (Muse review lane) rather than guessing it in a lane.

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

  3. added
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/triageQueue packet kind: verify, reproduce, and route this item
    on Nov 3, 2026
  4. developing-today commented on Nov 3, 2026

    @developing-today
    Contributor

    agent-note:v1
    state: triaged (coverage pass)
    Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 40 (priority/normal). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
    Found via: coverage pass 2026-11-03

  5. removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  6. 6 remaining items

  7. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    agent-note:v1
    state: done (queue task 8206 triaged)
    triage closed: issue still live, fix scoped as task 8762 (queued, queue/queued). owner's opendesign credential intent left open under user/review for the review lane.

  8. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Nov 3, 2026
  9. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  10. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  11. added a commit that references this issue on Nov 3, 2026
  12. dezren39 commented on Nov 3, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

  13. added a commit that references this issue on Nov 4, 2026
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/infrastructureInfrastructure / host-portability workmeta/enrichedIntake review done: acceptance criteria, links, and normalized labels addedpriority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/triageQueue packet kind: verify, reproduce, and route this itemuser/reviewNeeds a user-look: Muse reviews first and handles what it can

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions