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

  1. 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).
  2. 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.
  3. 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.
  4. 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.
  5. 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

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


AI-assisted analysis of firecrawl/open-lovable@69bd93bae7 (2026-08-28). Data as JSON: /api/errors/fdff66c66d3696ee. Report an issue: GitHub.