{"record":{"id":"d2cc0d76c944cab0","repo":"saadeghi/daisyui","slug":"unsafe-pr-css-in-filepath-reason","errorCode":null,"errorMessage":"Unsafe PR CSS in ${filePath}: ${reason}","messagePattern":"Unsafe PR CSS in (.+?): (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tailwind-play-share/pr-preview.mjs","lineNumber":289,"sourceCode":"}\n\nfunction isNonLocalCssUrl(value) {\n  if (!value) return false\n  const normalized = normalizeCssUrl(value)\n  return normalized.startsWith(\"//\") || /^[a-z][a-z0-9+.-]*:/i.test(normalized)\n}\n\nfunction normalizeCssUrl(value) {\n  return [...value.trim()]\n    .filter((character) => {\n      const codePoint = character.codePointAt(0)\n      return codePoint > 0x20 && codePoint !== 0x7f\n    })\n    .join(\"\")\n}\n\nfunction unsafePrCss(filePath, reason) {\n  throw new Error(`Unsafe PR CSS in ${filePath}: ${reason}`)\n}\n\nexport function assertSafePrCss(css, filePath = \"component stylesheet\") {\n  let index = 0\n\n  while (index < css.length) {\n    if (css.startsWith(\"/*\", index)) {\n      index = consumeCssComment(css, index)\n      continue\n    }\n    if (css[index] === '\"' || css[index] === \"'\") {\n      index = consumeCssString(css, index).end\n      continue\n    }\n    if (css[index] === \"@\") {\n      const atRule = consumeCssIdentifier(css, index + 1)\n      const name = atRule.value.toLowerCase()\n      if (forbiddenPrCssAtRules.has(name)) {","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/saadeghi/daisyui/blob/42b09e637e09467aa54a813a5aea53c1179aec75/packages/tailwind-play-share/pr-preview.mjs#L271-L307","documentation":"Thrown by unsafePrCss (called from assertSafePrCss) when the PR's component CSS contains content the preview pipeline refuses to render in Tailwind Play: a forbidden at-rule (@config, @plugin, @source), an external @import URL, or an external url() reference. The check is a security/safety gate before the CSS is shipped to play.tailwindcss.com.","triggerScenarios":"assertSafePrCss walks the changed component CSS at the head SHA and, for any @-rule whose name is in forbiddenPrCssAtRules or any url()/@import resolving to a non-local scheme, calls unsafePrCss(filePath, reason).","commonSituations":"A PR adds `@plugin \"...\"`, `@config \"...\"`, `@source \"...\"`, `@import url(\"https://...\")`, or `background: url(\"https://...\")` inside packages/daisyui/src/components/*.css. These are blocked because Tailwind Play cannot safely load them.","solutions":["Remove the forbidden @-rule or external URL from the component CSS in the PR.","For @plugin/@config/@source, keep them in the root stylesheet, not in per-component CSS.","Replace external url() references with relative or data: URLs if a URL is truly needed.","Re-run; the error names the file and the reason so you can locate the offending line."],"exampleFix":"/* before - packages/daisyui/src/components/btn.css */\n@import url(\"https://cdn.example.com/btn.css\");\n.btn { background: url(\"https://cdn.example.com/bg.png\"); }\n\n/* after */\n.btn { background: var(--btn-bg); }","handlingStrategy":"validation","validationCode":"import { assertSafePrCss } from \"./pr-preview.mjs\"\n// Run the safety check on the changed CSS BEFORE invoking the full preview pipeline.\nassertSafePrCss(changedCss, changedFilePath)","typeGuard":null,"tryCatchPattern":"try {\n  await generatePrPreview({ baseSha, headSha, output })\n} catch (error) {\n  if (/^Unsafe PR CSS in /.test(error.message)) {\n  // the message names the file + reason; edit the CSS and re-push\n  }\n  throw error\n}","preventionTips":["Keep @plugin/@config/@source and external URLs out of per-component CSS.","Run assertSafePrCss in CI lint before the preview job.","Treat the named file + reason in the message as the precise fix location."],"tags":["css","security","validation","pr-preview"],"backgroundTag":null,"analyzedSha":"42b09e637e09467aa54a813a5aea53c1179aec75","analyzedAt":"2026-08-13T04:10:09.555Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}