{"record":{"id":"59adfa2c298a7a6a","repo":"tailwindlabs/tailwindcss","slug":"source-paths-must-be-quoted","errorCode":null,"errorMessage":"`source(…)` paths must be quoted.","messagePattern":"`source\\(…\\)` paths must be quoted\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/tailwindcss/src/index.ts","lineNumber":209,"sourceCode":"\n      let params = segment(node.params, ' ')\n      for (let param of params) {\n        if (param.startsWith('source(')) {\n          let path = param.slice(7, -1)\n\n          // Keyword: `source(none)`\n          if (path === 'none') {\n            root = path\n            continue\n          }\n\n          // Explicit path: `source('…')`\n          if (\n            (path[0] === '\"' && path[path.length - 1] !== '\"') ||\n            (path[0] === \"'\" && path[path.length - 1] !== \"'\") ||\n            (path[0] !== \"'\" && path[0] !== '\"')\n          ) {\n            throw new Error('`source(…)` paths must be quoted.')\n          }\n\n          root = {\n            base: (ctx.context.sourceBase as string) ?? (ctx.context.base as string),\n            pattern: path.slice(1, -1),\n          }\n        }\n      }\n\n      utilitiesNode = node\n      features |= Features.Utilities\n    }\n\n    // Collect custom `@utility` at-rules\n    if (node.name === '@utility') {\n      if (ctx.parent !== null) {\n        throw new Error('`@utility` cannot be nested.')\n      }","sourceCodeStart":191,"sourceCodeEnd":227,"githubUrl":"https://github.com/tailwindlabs/tailwindcss/blob/16e94cbf7f965c5ad697e90e940b5e178efad67c/packages/tailwindcss/src/index.ts#L191-L227","documentation":"Thrown while parsing the parameters of a legacy `@tailwind utilities` directive when a `source(…)` argument is not wrapped in matching quotes. The parser explicitly allows `source(none)` unquoted, but every actual path must be a quoted string literal (`source('...')` or `source(\"...\")`), otherwise the parser cannot safely distinguish it from a keyword.","triggerScenarios":"Writing `@tailwind utilities source(./src/**/*.html)` (unquoted), or using mismatched quotes like `source(\"./src')`. Fires per `source(…)` segment inside the directive params.","commonSituations":"Upgrading a v3 stylesheet that used `@tailwind utilities` with `source(...)` and dropping the quotes during the edit. Copy-pasting glob examples from docs that stripped quotes in formatting.","solutions":["Wrap the path in matching single or double quotes: `@tailwind utilities source('./src/**/*.html')`.","Use `source(none)` (unquoted, the only permitted bareword) if you want to disable automatic source detection.","Remove the legacy `@tailwind utilities` directive entirely and use `@source` at-rules (the v4 idiom) for explicit candidate scanning."],"exampleFix":"/* before */\n@tailwind utilities source(./src/**/*.html);\n\n/* after */\n@tailwind utilities source('./src/**/*.html');","handlingStrategy":"validation","validationCode":"// Validate every source(...) argument in a @tailwind utilities directive.\nconst SOURCE_ARG = /source\\(([^)]*)\\)/g\n\nfunction validateUtilitiesSource(directive: string): string[] {\n  const errors: string[] = []\n  for (const m of directive.matchAll(SOURCE_ARG)) {\n    const inner = m[1].trim()\n    if (inner === 'none') continue\n    if (!(inner.startsWith('\"') && inner.endsWith('\"')) &&\n        !(inner.startsWith(\"'\") && inner.endsWith(\"'\"))) {\n      errors.push(`source(${inner}) must be quoted`)\n    }\n  }\n  return errors\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer the v4 `@source` at-rule over the legacy `@tailwind utilities source(...)` form.","Add a lint rule (stylelint) that flags unquoted arguments inside `source(...)`.","When migrating v3 files, mechanically wrap every `source(...)` path in single quotes."],"tags":["at-tailwind","source","quoting","legacy"],"backgroundTag":null,"analyzedSha":"16e94cbf7f965c5ad697e90e940b5e178efad67c","analyzedAt":"2026-08-12T06:02:42.469Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}