tailwindlabs/tailwindcss · error · Error
`@source` paths must be quoted.
Error message
`@source` paths must be quoted.
What it means
Thrown when the resolved `@source` path does not start and end with matching quotes. After stripping optional `not ` and `inline(...)` wrappers, the remaining path is checked the same way as `source(…)` — it must be a quoted string literal. The `not ` and `inline(...)` keywords themselves are detected by prefix checks before this guard.
Source
Thrown at packages/tailwindcss/src/index.ts:286
let inline = false
let path = node.params
if (path[0] === 'n' && path.startsWith('not ')) {
not = true
path = path.slice(4)
}
if (path[0] === 'i' && path.startsWith('inline(')) {
inline = true
path = path.slice(7, -1).trim()
}
if (
(path[0] === '"' && path[path.length - 1] !== '"') ||
(path[0] === "'" && path[path.length - 1] !== "'") ||
(path[0] !== "'" && path[0] !== '"')
) {
throw new Error('`@source` paths must be quoted.')
}
let source = path.slice(1, -1)
if (inline) {
let destination = not ? ignoredCandidates : inlineCandidates
let sources = segment(source, ' ')
for (let source of sources) {
for (let candidate of expand(source)) {
destination.push(candidate)
}
}
} else {
sources.push({
base: ctx.context.base as string,
pattern: source,
negated: not,
})View on GitHub (pinned to 16e94cbf7f)
Solutions
- Quote the path: `@source "./src/**/*.html"`.
- When negating or inlining, quote the inner path: `@source not("./legacy/**")`, `@source inline("./file.html")`.
- Use `@source none` only if you intend to disable all automatic source detection (note: `@source none` is not the keyword form — disable scanning via the build config instead).
Example fix
/* before */
@source not(./legacy/**);
@source inline(./icons.svg);
/* after */
@source not("./legacy/**");
@source inline("./icons.svg"); Defensive patterns
Strategy: validation
Validate before calling
// Reproduce the library's quoting check after stripping not/inline wrappers.
function validateSourceQuoted(raw: string): string | null {
let path = raw.trim()
if (path.startsWith('not ')) path = path.slice(4).trim()
if (path.startsWith('inline(')) path = path.slice(7, -1).trim()
const ok = (path.startsWith('"') && path.endsWith('"')) ||
(path.startsWith("'") && path.endsWith("'"))
return ok ? null : `@source path '${raw}' must be quoted`
} Prevention
- Always quote `@source` paths with single or double quotes.
- Apply the same quoting to the inner path of `not(...)` and `inline(...)` wrappers.
- Add a stylelint custom rule that enforces quoted strings inside `@source`.
When it happens
Trigger: Writing `@source ./src/**/*.html` (unquoted), `@source not(./legacy/**)`, or `@source inline(./file.html)`. Each requires the inner path to be quoted.
Common situations: Copy-pasting glob examples that lost quotes; mixing up `@source` syntax with shell-style unquoted globs.
Related errors
- `@source` cannot have a body.
- The prefix "${resolvedConfig.prefix}" is invalid. Prefixes m
- `addVariant('${name}')` defines an invalid variant name. Var
- `matchUtilities({ '${name}' : … })` defines an invalid utili
- `source(…)` paths must be quoted.
AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12).
Data as JSON: /api/errors/151bed5c129b94eb.
Report an issue: GitHub.