chatboxai/chatbox · error · Error
No response body
Error message
No response body
What it means
Thrown by the onboarding-guide chat loop after sendGuideMessage resolves. The guide API is a streaming POST (stream: true, retry: 0) that must return a readable Response.body; if the fetch resolved with a bodyless response the stream parser cannot run. The guard exists because a Response object can exist (status received) while body is null — e.g. opaque/error responses or empty 204s.
Source
Thrown at src/renderer/routes/guide/-hooks/useGuideSession.ts:702
// Prepare messages for API
const apiMessages: GuideMessage[] = messages
.filter((m) => m.role === 'user' || m.role === 'assistant')
.map((m) => ({
role: m.role,
content: m.content,
}))
apiMessages.push({ role: 'user', content })
// Send request with current onboarding step
const { uuid: deviceId } = await platform.getConfig()
const response = await sendGuideMessage(apiMessages, deviceId, {
onboardingStep,
isLoggedIn,
signal: abortControllerRef.current.signal,
})
if (!response.body) {
throw new Error('No response body')
}
// Parse streaming response
await parseStreamResponse(response.body.getReader(), {
setMessages,
setOnboardingStep,
pendingUpdateRef,
pendingTimeouts: pendingTimeoutsRef.current,
markGuideCompleted,
t,
})
} catch (err) {
if ((err as Error).name === 'AbortError') {
// User cancelled, just mark streaming as done
setMessages((prev) => {
const lastIdx = prev.length - 1
if (prev[lastIdx]?.isStreaming) {
return [View on GitHub (pinned to 81571269ad)
Solutions
- Inspect response.status and response.headers before throwing to give the user a meaningful error (e.g. 5xx vs CORS).
- Verify the guide API endpoint is reachable and returns text/event-stream with a non-empty body.
- Confirm CORS headers allow the origin and that no proxy buffers the stream.
- Retry on transient status codes (the retry:0 was set to avoid double-billing; consider a single retry only when status indicates no server-side processing started).
Example fix
// before
if (!response.body) {
throw new Error('No response body')
}
// after
if (!response.body) {
if (response.status === 0 || response.type === 'opaque') throw new Error('Guide request blocked (CORS/network)')
throw new Error(`No response body (HTTP ${response.status})`)
} Defensive patterns
Strategy: try-catch
Validate before calling
const response = await sendGuideMessage(apiMessages, deviceId, { onboardingStep, isLoggedIn, signal })
if (!response.ok || response.status === 0) {
throw new Error(`Guide request failed before streaming (HTTP ${response.status})`)
} Type guard
function hasReadableBody(r: Response): r is Response & { body: ReadableStream<Uint8Array> } {
return r.body != null && typeof r.body.getReader === 'function'
} Try / catch
try {
const response = await sendGuideMessage(...)
if (!hasReadableBody(response)) {
if (response.type === 'opaque' || response.status === 0) setError('Request blocked (network/CORS)')
else setError(`No response body (HTTP ${response.status})`)
return
}
await parseStreamResponse(response.body.getReader(), ...)
} catch (err) {
if ((err as Error).name === 'AbortError') return
setError((err as Error).message)
} Prevention
- Check response.ok and response.type before reading the body to give a precise error.
- Ensure CORS headers on the guide endpoint allow the app origin.
- Keep retry:0 but add explicit status-based messaging for empty responses.
When it happens
Trigger: sendGuideMessage returns a Response whose .body is null. Causes: the server replies 204 No Content or a non-streaming error with empty body, a network/CORS issue produces an opaque response (body null), a proxy returns headers then closes without a body, or the request was redirected. Because retry:0, transient transport errors surface here instead of being retried.
Common situations: Guide backend deployed without streaming support, reverse proxy buffering and stripping the body, CORS misconfiguration returning an opaque response, ad-blocker/privacy extension blocking the guide endpoint, or a 5xx where the server sent no body.
Related errors
- Status Code ${res.status}
- Knowledge base name cannot be empty
- Token exchange failed: ${error}
- Token refresh failed: ${error}
- ${response.status} ${response.statusText}: ${text}
AI-assisted analysis of chatboxai/chatbox@81571269ad (2026-08-12).
Data as JSON: /api/errors/00d2819ebdcde208.
Report an issue: GitHub.