firecrawl/open-lovable · error
Failed to generate recreation
Error message
Failed to generate recreation
What it means
This error is thrown by AISandboxPage's URL-recreation flow after it finishes consuming the streaming response from /api/generate-ai-code-stream. The stream ended with HTTP 200, but the client never received an SSE event of type 'complete' carrying a non-empty `generatedCode`, so `generatedCode` is still an empty string and the code throws. It is a client-side guard meaning 'the AI backend streamed nothing usable' — the actual failure (model error, mid-stream abort, missing complete event) happened upstream or during SSE parsing.
Source
Thrown at app/generation/page.tsx:3233
: `Successfully recreated ${url} as a modern React app${homeContextInput ? ` with your requested context: "${homeContextInput}"` : ''}! The scraped content is now in my context, so you can ask me to modify specific sections or add features based on the original site.`,
'ai',
{
scrapedUrl: url,
scrapedContent: brandExtensionMode ? { brandGuidelines } : scrapeData,
generatedCode: generatedCode
}
);
setConversationContext(prev => ({
...prev,
generatedComponents: [],
appliedCode: [...prev.appliedCode, {
files: [],
timestamp: new Date()
}]
}));
} else {
throw new Error('Failed to generate recreation');
}
setUrlInput('');
setUrlStatus([]);
setHomeContextInput('');
// Clear generation progress and all screenshot/design states
setGenerationProgress(prev => ({
...prev,
isGenerating: false,
isStreaming: false,
status: 'Generation complete!'
}));
// Clear screenshot and preparing design states to prevent them from showing on next run
setIsScreenshotLoaded(false); // Reset loaded state
setUrlScreenshot(null);
setIsPreparingDesign(false);View on GitHub (pinned to 69bd93bae7)
Solutions
- Inspect the server logs / network tab for /api/generate-ai-code-stream to find the real upstream failure (missing AI API key, provider error, quota).
- Fix the SSE parser to buffer partial lines across reader.read() chunks before splitting on '\n', so a complete event split across chunks is not lost.
- Log failed JSON.parse events in the inner catch (line 3185-3187) instead of only console.error, to see if the complete event was malformed.
- On the server, always emit a final 'complete' (or 'error') SSE event in a finally block so the client never ends a stream without a terminal event.
- Add client-side retry: catch this error and re-issue the generation request once before surfacing failure to the user.
Example fix
// before: per-chunk naive parse loses split SSE lines
const chunk = decoder.decode(value);
const lines = chunk.split('\n');
for (const line of lines) {
if (line.startsWith('data: ')) {
const data = JSON.parse(line.slice(6));
...
}
}
// after: buffer partial lines so the 'complete' event is never missed
let buffer = '';
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 = JSON.parse(line.slice(6));
if (data.type === 'complete') generatedCode = data.generatedCode;
}
}
}
if (!generatedCode) throw new Error('Failed to generate recreation'); Defensive patterns
Strategy: retry
Validate before calling
async function streamHasCompleteEvent(url: string, body: object): Promise<boolean> {
const res = await fetch(url, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) });
if (!res.ok || !res.body) return false;
const text = await res.text();
return text.split('\n').some(l => l.startsWith('data: ') && JSON.parse(l.slice(6)).type === 'complete');
} Type guard
function isCompleteEvent(d: unknown): d is { type: 'complete'; generatedCode: string; explanation?: string } {
return typeof d === 'object' && d !== null && (d as any).type === 'complete' && typeof (d as any).generatedCode === 'string' && (d as any).generatedCode.trim().length > 0;
} Try / catch
try {
await generateRecreation(url);
} catch (e) {
if (e instanceof Error && e.message === 'Failed to generate recreation') {
setGenerationProgress(prev => ({ ...prev, isGenerating: false, isStreaming: false, status: 'Generation failed — retrying...' }));
await generateRecreation(url); // single retry
} else {
throw e;
}
} Prevention
- Buffer partial SSE lines across read() chunks instead of splitting each decoded chunk on newlines.
- Verify the AI provider key/quota is configured in the environment before starting a long generation.
- Ensure the server route always emits a terminal 'complete' or 'error' SSE event, even on failure (try/finally).
- Log and surface failed JSON.parse of SSE data lines rather than swallowing them.
- Treat an empty generatedCode as a distinct UI state (retryable) instead of letting the throw escape as an unhandled promise rejection.
When it happens
Trigger: The SSE stream from POST /api/generate-ai-code-stream closes without ever emitting a `data: {"type":"complete","generatedCode":...}` event, or the complete event's generatedCode is empty/falsy. Also caused by: SSE JSON lines that fail JSON.parse (silently swallowed by the inner try/catch at line 3185), the server erroring mid-stream, truncated chunks that split a `data:` line across reader.read() boundaries so `line.startsWith('data: ')` never matches the complete event, or the model returning prose with no <file> payload.
Common situations: AI provider API key missing/expired or rate-limited server-side so the stream errors mid-way; very long generation timing out and the connection dropping before the complete event; a chunk boundary splitting the final SSE line (the naive `chunk.split('\n')` parser does not buffer partial lines); model output filtered out by the tag-stripping/filters; deployment where the route handler silently returns an empty stream after an upstream failure.
Related errors
- Failed to apply code: ${response.statusText}
- ${finalData?.error || 'Failed to apply code'}
- HTTP error! status: ${response.status}
- Failed to generate code
AI-assisted analysis of firecrawl/open-lovable@69bd93bae7 (2026-08-28).
Data as JSON: /api/errors/fdff66c66d3696ee.
Report an issue: GitHub.