firecrawl/open-lovable · error
Failed to extract brand styles
Error message
Failed to extract brand styles
What it means
Thrown when the brand-styles extraction endpoint returns a non-2xx HTTP status during brand-extension mode. The client posted { url, prompt: brandExtensionPrompt } and extractResponse.ok was false, so the brand guidelines could not be fetched and generation of the brand-matched component cannot proceed. It is a coarse message: the HTTP status/body must be checked separately for the real cause.
Source
Thrown at app/generation/page.tsx:2728
let scrapeData: ScrapeData | undefined;
let brandGuidelines: any;
if (brandExtensionMode) {
// === BRAND EXTENSION MODE ===
addChatMessage('Extracting brand styles from the website...', 'system');
// Call the brand extraction endpoint
const extractResponse = await fetch('/api/extract-brand-styles', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
url,
prompt: brandExtensionPrompt
})
});
if (!extractResponse.ok) {
throw new Error('Failed to extract brand styles');
}
brandGuidelines = await extractResponse.json();
if (!brandGuidelines.success) {
throw new Error(brandGuidelines.error || 'Failed to extract brand styles');
}
// Display branding summary with visual UI
addChatMessage(`Acquired branding format from ${cleanUrl}`, 'system', {
brandingData: brandGuidelines.guidelines,
sourceUrl: cleanUrl
});
addChatMessage(`Building your custom component using these brand guidelines...`, 'system');
// Clear the flags after use
sessionStorage.removeItem('brandExtensionMode');
sessionStorage.removeItem('brandExtensionPrompt');View on GitHub (pinned to 69bd93bae7)
Solutions
- Inspect the Network tab for the extraction request's status code and body to see the underlying reason
- Validate the URL is well-formed and publicly reachable (try curl-ing it) before retrying
- If the site blocks bots (403/Cloudflare), try a different public page of the same brand or a cached version
- Check the extraction route's server logs for timeouts or upstream fetch errors and increase its timeout if needed
- Retry once for transient 5xx/timeout failures
Example fix
// before
if (!extractResponse.ok) {
throw new Error('Failed to extract brand styles');
}
// after
if (!extractResponse.ok) {
let detail = '';
try { detail = await extractResponse.text(); } catch {}
throw new Error(`Failed to extract brand styles (${extractResponse.status}): ${detail || extractResponse.statusText}`);
} Defensive patterns
Strategy: validation
Validate before calling
function isExtractableUrl(url: string): boolean {
try { const u = new URL(url); return u.protocol === 'http:' || u.protocol === 'https:'; }
catch { return false; }
}
if (!isExtractableUrl(url)) throw new Error('Enter a valid public http(s) URL'); Type guard
interface BrandGuidelines { success: boolean; error?: string; guidelines?: unknown }
function hasGuidelines(d: unknown): d is BrandGuidelines & { success: true; guidelines: Record<string, unknown> } {
return typeof d === 'object' && d !== null && (d as BrandGuidelines).success === true && (d as BrandGuidelines).guidelines != null;
} Try / catch
try {
const res = await fetch(EXTRACT_URL, { method: 'POST', body: JSON.stringify({ url, prompt: brandExtensionPrompt }) });
if (!res.ok) throw new Error(`Brand extraction HTTP ${res.status}`);
brandGuidelines = await res.json();
if (!hasGuidelines(brandGuidelines)) throw new Error(brandGuidelines?.error || 'No usable brand guidelines extracted');
} catch (err: any) {
addChatMessage(`Brand extraction failed: ${err.message}. Try another public page.`, 'system');
} Prevention
- Validate URL format and scheme client-side before submitting
- Prefer public, static-HTML pages; warn users about login-walled or bot-protected sites
- Read the extraction response body for the real cause instead of a generic message
- Set/verify a reasonable server-side fetch timeout for slow sites
- Fall back to manual brand input when automated extraction fails
When it happens
Trigger: fetch to the extract-brand-styles route resolves with extractResponse.ok === false: the target site blocked scraping (403 from upstream, surfaced as route failure), the route handler threw (invalid URL, fetch timeout), or the route is missing (404).
Common situations: User submits a URL behind a login/Cloudflare protection so server-side scraping is blocked; malformed URL (missing protocol) fails server-side URL validation; extraction route times out on slow sites; deployment lacks the extraction route; target site returns non-HTML content the extractor cannot parse and the route 500s.
Related errors
- Failed to scrape website
- Firecrawl API returned ${firecrawlResponse.status}
- Failed to apply code: ${response.statusText}
- HTTP error! status: ${response.status}
- ${brandGuidelines.error || 'Failed to extract brand styles'}
AI-assisted analysis of firecrawl/open-lovable@69bd93bae7 (2026-08-28).
Data as JSON: /api/errors/9fec75d1348cad47.
Report an issue: GitHub.