{"record":{"id":"c9a76d2ddca4d95c","repo":"amruthpillai/reactive-resume","slug":"the-semantic-stylesheet-could-not-be-rendered","errorCode":null,"errorMessage":"The semantic stylesheet could not be rendered.","messagePattern":"The semantic stylesheet could not be rendered\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/pdf/src/browser.tsx","lineNumber":77,"sourceCode":"\t...options\n}: CreateResumePdfBlobResultOptions): Promise<ResumePdfRenderResult<Blob>> => {\n\tconst normalizedOptions = { ...options, data: parseResumeData(options.data) };\n\tconst resolvedInspection = inspection ?? inspectResumePdf(normalizedOptions);\n\tif (hasSemanticErrors(resolvedInspection)) {\n\t\treturn { ok: false, diagnostics: resolvedInspection.diagnostics };\n\t}\n\n\treturn {\n\t\tok: true,\n\t\tvalue: await renderResumePdfBlob(normalizedOptions),\n\t\tdiagnostics: resolvedInspection.diagnostics,\n\t};\n};\n\nexport const createResumePdfBlob = async (options: CreateResumePdfBlobOptions): Promise<Blob> => {\n\tconst result = await createResumePdfBlobResult(options);\n\tif (!result.ok) {\n\t\tthrow new Error(\"The semantic stylesheet could not be rendered.\", { cause: result.diagnostics });\n\t}\n\treturn result.value;\n};\n","sourceCodeStart":59,"sourceCodeEnd":81,"githubUrl":"https://github.com/amruthpillai/reactive-resume/blob/3a5b12e2a40374a9571988701fcb75c5a1831c42/packages/pdf/src/browser.tsx#L59-L81","documentation":"Thrown by createResumePdfBlob (browser adapter) when createResumePdfBlobResult returns ok:false, which happens when hasSemanticErrors(resolvedInspection) is true — i.e. the resume's semantic stylesheet produced at least one diagnostic with severity 'error' during compileStylesheet/resolveStylesheet. The thrown Error includes a `cause` field holding the diagnostics array (SemanticCssDiagnostic[]), so callers can inspect specific failures. This is the browser-side entry point used by the web preview/export.","triggerScenarios":"Calling createResumePdfBlob with resume data whose metadata.stylesheet.mode is 'semantic' and whose authored CSS contains an error-level diagnostic (unknown element, invalid attribute, malformed selector, unsupported property, etc.). Also when a publicStyleProjection fails to compile. The preflight in inspectResumePdf runs synchronously before any PDF bytes are produced, so the throw happens before rendering.","commonSituations":"User-authored semantic CSS with a typo or unsupported construct. A template/stylesheet migration that introduced an invalid rule. Programmatic resume data with a stylesheet.applied payload that doesn't compile. Switching a resume from 'legacy' to 'semantic' mode without fixing pre-existing CSS errors.","solutions":["Call createResumePdfBlobResult instead and inspect the returned `diagnostics` array to find the specific error-level diagnostic(s) (each has severity, message, and location).","Fix the offending rule(s) in the semantic stylesheet source (data.metadata.stylesheet.applied.text) based on the diagnostic messages, then retry.","If you do not need the throw, use the Result-style API (createResumePdfBlobResult) which returns { ok:false, diagnostics } instead of throwing, and degrade gracefully.","Temporarily switch the resume's stylesheet mode back to 'legacy' (data.metadata.stylesheet.mode) to unblock export while the semantic CSS is repaired."],"exampleFix":"// before: throws, loses diagnostics detail\ntry {\n  const blob = await createResumePdfBlob({ data });\n} catch (e) {\n  console.error(e.cause); // diagnostics array, but flow interrupted\n}\n\n// after: use the Result API to inspect diagnostics before deciding\nconst result = await createResumePdfBlobResult({ data });\nif (!result.ok) {\n  for (const d of result.diagnostics) {\n    if (d.severity === 'error') console.error(d.message, d.location);\n  }\n  return;\n}\nconst blob = result.value;","handlingStrategy":"try-catch","validationCode":"import { inspectResumePdf, hasSemanticErrors } from '@reactive-resume/pdf/browser';\n\nconst inspection = inspectResumePdf({ data });\nif (hasSemanticErrors(inspection)) {\n  // show inspection.diagnostics to the user; do not call createResumePdfBlob\n  for (const d of inspection.diagnostics) console.warn(d.message);\n}","typeGuard":"import type { ResumePdfRenderResult } from '@reactive-resume/pdf/semantic';\nfunction isOk<T>(r: ResumePdfRenderResult<T>): r is Extract<ResumePdfRenderResult<T>, { ok: true }> {\n  return r.ok;\n}","tryCatchPattern":"import { createResumePdfBlobResult } from '@reactive-resume/pdf/browser';\n\nconst result = await createResumePdfBlobResult({ data });\nif (!result.ok) {\n  // result.diagnostics contains the error-level diagnostics\n  handleDiagnostics(result.diagnostics);\n  return;\n}\nconst blob = result.value;","preventionTips":["Use the Result-style API (createResumePdfBlobResult) instead of the throwing wrapper so diagnostics are not lost.","Run inspectResumePdf before rendering and surface diagnostics in the builder UI.","When reading the thrown Error, always inspect error.cause for the diagnostics array.","Keep a 'legacy' mode fallback for resumes with broken semantic CSS."],"tags":["pdf","semantic-stylesheet","browser","diagnostics","render"],"backgroundTag":null,"analyzedSha":"3a5b12e2a40374a9571988701fcb75c5a1831c42","analyzedAt":"2026-08-12T22:31:22.666Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}