{"record":{"id":"00bf4435ff6d3316","repo":"firecrawl/open-lovable","slug":"brandguidelines-error-failed-to-extract-bran","errorCode":null,"errorMessage":"${brandGuidelines.error || 'Failed to extract brand styles'}","messagePattern":"\\$\\{brandGuidelines\\.error \\|\\| 'Failed to extract brand styles'\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/generation/page.tsx","lineNumber":2734,"sourceCode":"\n          // Call the brand extraction endpoint\n          const extractResponse = await fetch('/api/extract-brand-styles', {\n            method: 'POST',\n            headers: { 'Content-Type': 'application/json' },\n            body: JSON.stringify({\n              url,\n              prompt: brandExtensionPrompt\n            })\n          });\n\n          if (!extractResponse.ok) {\n            throw new Error('Failed to extract brand styles');\n          }\n\n          brandGuidelines = await extractResponse.json();\n\n          if (!brandGuidelines.success) {\n            throw new Error(brandGuidelines.error || 'Failed to extract brand styles');\n          }\n\n          // Display branding summary with visual UI\n          addChatMessage(`Acquired branding format from ${cleanUrl}`, 'system', {\n            brandingData: brandGuidelines.guidelines,\n            sourceUrl: cleanUrl\n          });\n          addChatMessage(`Building your custom component using these brand guidelines...`, 'system');\n\n          // Clear the flags after use\n          sessionStorage.removeItem('brandExtensionMode');\n          sessionStorage.removeItem('brandExtensionPrompt');\n\n        } else {\n          // === NORMAL CLONE MODE ===\n          // Check if we have pre-scraped markdown content from search results\n          const storedMarkdown = sessionStorage.getItem('siteMarkdown');\n        if (storedMarkdown) {","sourceCodeStart":2716,"sourceCodeEnd":2752,"githubUrl":"https://github.com/firecrawl/open-lovable/blob/69bd93bae7a9c97ef989eb70aabe6797fb3dac89/app/generation/page.tsx#L2716-L2752","documentation":"Application-level variant of the brand-extraction failure: the extraction endpoint returned HTTP 200 but its JSON body has success === false, so brandGuidelines.error (or the fallback text) is thrown. The server reached the target site (or at least handled the request) but its extraction step failed and reported why in the payload.","triggerScenarios":"extractResponse.json() yields { success: false, error: '...' }: the extractor fetched the page but found no styles/colors/typography it could parse, the page returned a soft error page (200 with 'not found' HTML), or server-side parsing threw and was converted into a success:false payload.","commonSituations":"Target site is a JS-only SPA whose styles are not in the initial HTML; site uses minimal/unparseable CSS; URL points to a 404/soft-404 page that still returns 200; extractor's CSS parser fails on modern syntax (nested CSS, container queries); site content changed and the extraction heuristics no longer match.","solutions":["Read brandGuidelines.error from the response — the thrown message contains it","Verify the URL serves a real, publicly accessible HTML page with standard CSS (test with curl/view-source)","Try a different page on the same brand site (e.g. the homepage) that has richer styling","Retry once in case the target site served a transient error page","If the site is a client-rendered SPA, use a URL known to include static styles or fall back to manual brand input"],"exampleFix":"// before\nif (!brandGuidelines.success) {\n  throw new Error(brandGuidelines.error || 'Failed to extract brand styles');\n}\n// after\nif (!brandGuidelines?.success || !brandGuidelines?.guidelines) {\n  throw new Error(brandGuidelines?.error || 'Extraction returned no usable brand guidelines');\n}","handlingStrategy":"type-guard","validationCode":"const data = await extractResponse.json();\nif (typeof data !== 'object' || data === null || data.success !== true || !data.guidelines) {\n  throw new Error(data?.error || 'Extraction returned no usable brand guidelines');\n}","typeGuard":"function isBrandSuccess(d: unknown): d is { success: true; guidelines: Record<string, unknown>; error?: undefined } {\n  return typeof d === 'object' && d !== null &&\n    (d as any).success === true && typeof (d as any).guidelines === 'object' && (d as any).guidelines !== null;\n}","tryCatchPattern":"try {\n  const data = await extractResponse.json();\n  if (!isBrandSuccess(data)) throw new Error(data?.error || 'Failed to extract brand styles');\n  brandGuidelines = data;\n} catch (err: any) {\n  addChatMessage(`Branding failed: ${err.message}`, 'system');\n  // fall back to manual brand settings input\n}","preventionTips":["Validate the parsed payload's shape (success flag + guidelines present) before proceeding","Check that the URL serves real styled HTML (curl / view-source) before extraction","Offer a fallback path (manual brand colors/fonts) when extraction reports success:false","Retry once to rule out transient challenge/error pages from the target site","Log data.error verbatim to diagnose parser gaps on modern CSS"],"tags":["scraping","branding","api-response","validation"],"backgroundTag":"scrape-request-blocked","analyzedSha":"69bd93bae7a9c97ef989eb70aabe6797fb3dac89","analyzedAt":"2026-08-28T22:20:32.339Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}