• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stacklok / toolhive / 32710296244
70%

Build:
DEFAULT BRANCH: main
Ran 24 Aug 2026 09:20AM UTC
Jobs 1
Files 893
Run time 2min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

24 Aug 2026 09:12AM UTC coverage: 69.241% (+0.005%) from 69.236%
32710296244

push

github

web-flow
Report a rejected stored credential as re-login required (#6389)

* fix(auth): report a rejected stored credential as re-login required

When a non-interactive token source exhausted every cache tier, Token()
returned the last error verbatim. For a refresh token the IdP had rejected
(expired, revoked, or rotated out from under us) that meant the raw
invalid_grant surfaced instead of the caller's FallbackErr sentinel.

That inverted the two outcomes. A cache MISS got the actionable "you must log
in again" error, while a DEAD credential, the case that genuinely requires an
interactive login, got an opaque OAuth error that every downstream consumer
reads as a transient provider fault. The LLM proxy renders it as a 502
server_error rather than the 401 that names `thv llm setup`, so a user whose
refresh token died sees a gateway problem and has nothing to act on.

Token() now classifies the terminal error: a permanent token-endpoint verdict
is reported as FallbackErr with the cause still reachable via errors.As, while
everything else (5xx, 429, a WAF page, a locked keyring) keeps surfacing
verbatim so callers can retry or fix the real problem. The rendered message
carries only the sentinel and the RFC 6749 error code, never the raw
token-endpoint response body, which can echo back bearer material.

The stored credential is deliberately not deleted on a rejection. With an IdP
that rotates refresh tokens, a sibling process may have just written a newer
token under the same key and the next call re-reads the secrets provider;
deleting here would destroy that cross-process recovery.

The transient/permanent rules move to a new leaf package, pkg/auth/oautherr,
so the token source and the workload auth monitor share one implementation
instead of each carrying its own copy. The monitor's private helpers now
delegate to it, leaving its behaviour and tests unchanged.

ErrTokenRequired's wording widens from "no cached credentials found" to "no
usable cached credenti... (continued)

42 of 42 new or added lines in 3 files covered. (100.0%)

6 existing lines in 3 files now uncovered.

74532 of 107642 relevant lines covered (69.24%)

88.53 hits per line

Coverage Regressions

Lines Coverage ∆ File
3
96.18
-0.57% pkg/authz/authorizers/cedar/core.go
2
50.66
-0.53% pkg/transport/stdio.go
1
96.77
-3.23% pkg/foreach/foreach.go
Jobs
ID Job ID Ran Files Coverage
1 32710296244.1 24 Aug 2026 09:20AM UTC 893
69.24
GitHub Action Run
Source Files on build 32710296244
  • Tree
  • List 893
  • Changed 8
  • Source Changed 3
  • Coverage Changed 8
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #32710296244
  • 2b115568 on github
  • Prev Build on main (#32472617314)
  • Next Build on main (#32712609892)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc