GitbookIO/gitbook · error · Error
No response found
Error message
No response found
What it means
Thrown inside streamRenderAIMessage's parseResponse helper in the GitBook AI server actions when an AI stream from the API finishes without ever emitting a response_finish event. parseResponse iterates the whole EventIterator looking for that event to capture the responseId; if the stream ends (or errors upstream) without it, the response Promise rejects with 'No response found' and the derived stream is failed with the same error.
Source
Thrown at packages/gitbook/src/components/AI/server-actions/api.tsx:165
const stream = new EventIterator<T>((queue) => {
(async () => {
let foundResponse = false;
for await (const event of responseStream) {
const parsed = await parse(event);
if (parsed !== undefined) {
queue.push(parsed);
}
if (event.type === 'response_finish') {
foundResponse = true;
resolveResponse({ responseId: event.response.id ?? null });
}
}
if (!foundResponse) {
throw new Error('No response found');
}
})().then(
() => {
queue.stop();
},
(error) => {
queue.fail(error);
}
);
});
return { stream, response };
}
View on GitHub (pinned to db67585ee2)
Solutions
- Retry the render call: this most often reflects a dropped stream, so wrap the await in a retry with backoff.
- Inspect the raw stream events (log every event.type) to confirm whether any event arrives at all, distinguishing an auth/permission failure from a network drop.
- Check that the organization/site actually has AI enabled and the request context (orgId, siteId, URL data) is correct so the API opens a real stream.
- If it persists, update the client/API versions — a mismatch between expected and emitted event types causes exactly this silent end-of-stream.
Example fix
// before
const { stream, response } = streamRenderAIMessage(...);
const { responseId } = await response; // throws 'No response found'
// after
const { stream, response } = streamRenderAIMessage(...);
const { responseId } = await response.catch((error) => {
if (error.message === 'No response found') {
return { responseId: null }; // degrade gracefully, stream content may still be usable
}
throw error;
}); Defensive patterns
Strategy: retry
Validate before calling
// Cannot validate before the call (depends on upstream stream health); guard usage instead: // only call streamRenderAIMessage when AI is enabled and the context is valid.
Try / catch
const { stream, response } = streamRenderAIMessage(...);
const { responseId } = await response.catch((error) => {
if (error instanceof Error && error.message === 'No response found') {
return { responseId: null };
}
throw error;
}); Prevention
- Treat responseId as optional; the content stream may still be complete.
- Retry once with backoff — dropped streams are usually transient.
- Log the raw event types of the stream when debugging to distinguish an empty stream from an early error event.
When it happens
Trigger: Calling streamRenderAIMessage and awaiting its response promise when the upstream API stream closes without a response_finish event; the API returns an immediate error/disconnect event that terminates the iterator early; a network interruption or proxy timeout between the Next.js server and the GitBook API ends the SSE stream prematurely; API schema changes rename or drop the response_finish event type.
Common situations: Transient network failures or Cloudflare/edge timeouts severing long AI streams; the AI feature being mid-rollout on the API side so streams end abruptly; using a stale API client whose event type names no longer match what the backend emits.
Related errors
- AI Search is not enabled for this site.
- AI is not enabled for this site.
- The AI Assistant is not enabled for this site.
- useAI must be used within AIContextProvider
- There is no previous response to rate.
AI-assisted analysis of GitbookIO/gitbook@db67585ee2 (2026-08-28).
Data as JSON: /api/errors/0690ef79771a9280.
Report an issue: GitHub.