windmill-labs/windmill · error
No response body for SSE stream
Error message
No response body for SSE stream
What it means
The Windmill CLI's `wmill app dev` command streams run/job updates from the backend via Server-Sent Events (`/jobs_u/getupdate_sse/<jobId>`). After the fetch succeeds (HTTP status OK and no auth-gateway challenge), it calls `response.body.getReader()`; if the response has no readable body it throws this error, because there is no stream to forward to the browser WebSocket.
Source
Thrown at cli/src/commands/app/dev.ts:1984
const response = await fetch(sseUrl, {
headers: {
Accept: "text/event-stream",
Authorization: `Bearer ${token}`,
...extraHeaders,
},
});
await detectAuthGatewayChallenge(response, sseUrl);
if (!response.ok) {
throw new Error(
`SSE request failed: ${response.status} ${response.statusText}`,
);
}
const reader = response.body?.getReader();
if (!reader) {
throw new Error("No response body for SSE stream");
}
const decoder = new TextDecoder();
let buffer = "";
try {
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split("\n");
buffer = lines.pop() || "";
for (const line of lines) {
if (line.startsWith("data: ")) {
const data = line.slice(6);
try {View on GitHub (pinned to e474e8803c)
Solutions
- Check that the URL is reachable and returns a real `text/event-stream` response (curl -N the SSE URL with a Bearer token).
- Verify no proxy/auth gateway intercepts the response; check `detectAuthGatewayChallenge` output and instance base URL (`--baseUrl`).
- Upgrade the CLI runtime (Node/Deno/Bun) to a version with full streaming fetch support.
- Retry the `wmill app dev` command; if persistent, capture the raw response with curl and inspect headers/body.
Example fix
// defensive: report status when body is missing
const reader = response.body?.getReader();
if (!reader) {
throw new Error(`No response body for SSE stream (status ${response.status}, content-type ${response.headers.get('content-type')})`);
} Defensive patterns
Strategy: try-catch
Validate before calling
const res = await fetch(sseUrl, { headers: { Accept: 'text/event-stream', Authorization: `Bearer ${token}` } });
if (!res.ok || !res.body) throw new Error(`SSE unavailable: ${res.status}`); Type guard
function hasBody(r: Response): r is Response & { body: ReadableStream } { return r.body !== null; } Try / catch
try { await streamJobWithSSE(...) } catch (e) { if (String(e).includes('No response body')) fallbackToPolling(jobId); else throw e; } Prevention
- Verify the SSE endpoint with curl -N before automating against it
- Check for proxy/auth-gateway interference with streaming responses
- Use a runtime with full streaming fetch support (modern Node 18+/Deno/Bun)
- Implement a polling fallback for job status when SSE fails
When it happens
Trigger: Calling the SSE endpoint on a server or fetch runtime that returns a null `response.body` — e.g. an unexpected HTTP method/result, a proxy that stripped or buffered the body, or a runtime whose fetch implementation does not expose a ReadableStream for streaming responses.
Common situations: Corporate proxies or auth gateways in front of the Windmill instance intercepting the event-stream request; misconfigured reverse proxy returning an empty 200; running the CLI in a Node/Deno version with limited streaming fetch support; a redirect to a login page that returns OK with an HTML body-less response.
Related errors
- Dependency generation failed: ${queueResponse.status} ${queu
- Failed to poll dependencies job ${jobId}: ${e?.message ?? e}
- Failed to poll flow dependencies job ${jobId}: ${e?.message
- Couldn't fetch resource types from hub ${hubBaseUrl}: ${(awa
- Couldn't fetch resource types from public hub:
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/cda5e6f547f6a6c7.
Report an issue: GitHub.