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

stacklok / toolhive / 30356783315
70%

Build:
DEFAULT BRANCH: main
Ran 28 Jul 2026 12:03PM UTC
Jobs 1
Files 851
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

28 Jul 2026 11:55AM UTC coverage: 69.798% (-0.02%) from 69.818%
30356783315

push

github

web-flow
Frame SSE filter-failure errors as SSE events (#6087)

On the text/event-stream path, writeErrorResponse wrote a bare JSON
object straight into the stream body with no "data: " prefix. Per the
WHATWG event-stream grammar that parses as a field named {"jsonrpc",
and an unrecognized field is ignored, so the client never saw the
error at all: it saw a stream that stopped with no response to its
request and hung until its own timeout. That is the worst available
failure mode, because the caller cannot tell it apart from a dead
server.

Emit the error as a "data:" line in place of the frame that failed and
let the loop keep going, so the separator and the trailing
reconciliation frame it exactly as they frame a successfully filtered
frame. Remaining frames are unrelated to the failed one, so continuing
also removes the truncation that the old early return caused by
skipping the reconciliation.

The mid-stream WriteHeader(500) is gone: Flush() has already committed
the headers by then, and text/event-stream carrying a bare JSON body is
unreadable by an SSE client regardless.

writeSSEDataLine's stop return value collapses into err != nil, which
also fixes a latent wart where the caller discarded a non-nil error
whenever stop was false.

This buys framing parity with the success path, not general SSE
correctness. A body carrying more than one event is still mis-framed by
the separator reconciliation, and a body with no trailing blank line
still gets no terminator. Both predate this change, apply equally when
filtering succeeds, and are left alone.

The failure branch is unreachable from any real backend response, so
the tests cover it at the seam rather than through FlushAndFilter: no
test-only injection point was added to production code.

Refs #6037

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>

21 of 31 new or added lines in 1 file covered. (67.74%)

28 existing lines in 8 files now uncovered.

81529 of 116807 relevant lines covered (69.8%)

97.35 hits per line

Uncovered Changes

Lines Coverage ∆ File
10
83.92
-0.36% pkg/authz/response_filter.go

Coverage Regressions

Lines Coverage ∆ File
7
61.31
-0.6% pkg/workloads/manager.go
6
20.11
-3.45% pkg/client/manager.go
3
73.79
-2.91% pkg/state/local.go
3
67.14
-4.29% pkg/state/runconfig.go
3
80.56
-0.7% pkg/transport/proxy/httpsse/http_proxy.go
2
83.92
-0.36% pkg/authz/response_filter.go
2
73.78
-0.24% pkg/transport/proxy/streamable/streamable_proxy.go
2
82.06
-0.21% pkg/vmcp/composer/workflow_engine.go
Jobs
ID Job ID Ran Files Coverage
1 30356783315.1 28 Jul 2026 12:03PM UTC 851
69.8
GitHub Action Run
Source Files on build 30356783315
  • Tree
  • List 851
  • Changed 9
  • Source Changed 1
  • Coverage Changed 9
Coverage ∆ File Lines Relevant Covered Missed Hits/Line
  • Back to Repo
  • Github Actions Build #30356783315
  • f805322e on github
  • Prev Build on main (#30355557706)
  • Next Build on main (#30358418301)
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