Skip to main content
← Back to list
01Issue
BugOpenSwamp CLIPublic
AssigneesNone

Relationships

#4445 swamp-lib: workflowRunStream drops a refusal and ends as if nothing went wrong

Opened by skunk-ape · 11/5/2026

Summary

SwampClient.workflowRunStream() in @swamp-club/swamp-lib drops an error frame when the consumer is already waiting for the next event. A refused run ends the stream as if nothing went wrong: no events, no exception. A caller can read a refused run as a clean finish.

Reproduction

Call workflowRunStream with a token that has no run grant on the workflow:

for await (const e of client.workflowRunStream({ workflowIdOrName: "gated" })) { /* never entered */ }
// the loop exits normally

Seen on abeba3f6a with swamp-lib 0.2.0 from packages/client, under Node 26, against a local serve in token mode, using a read-only user.

Call Result
Raw WebSocket error frame: unauthorized, "Access denied: user:bob does not have 'run' on workflow:gated"
workflowRunStream no events, and nothing thrown
workflowRun rejected with that unauthorized error

Serve refused correctly and no run started. The loss is only in the client.

Cause

In packages/client/client.ts, AsyncIterableQueue.error() stores the error, then settles a waiting next() with { done: true }. The stored error is only raised by a later next(), and for await never makes one after done. An error that arrives before the consumer starts waiting is raised correctly, so this depends on timing.

modelMethodRunStream uses the same queue. I read that from the code and haven't tested it.

Expected

A waiting next() rejects with the error, so the stream throws SwampClientError.

Impact

Any integration using the stream helpers treats refusals, and possibly other errors, as success with no output. A test Slack app showed nothing at all when a person without run tried to start a workflow.

Related: #4438. workflowRun and workflowRunStream currently have opposite failures, so neither is safe alone for a workflow that can both suspend and be refused.

02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

11/5/2026, 7:30:06 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.