tailwindlabs/tailwindcss · error · Error
`@source` cannot have a body.
Error message
`@source` cannot have a body.
What it means
Thrown when an `@source` at-rule has any child nodes (`node.nodes.length > 0`). `@source` is a statement-style at-rule that takes its arguments in the prelude (`@source "./**/*.html"`); giving it a curly-brace body is structurally invalid and is rejected before the path is even inspected.
Source
Thrown at packages/tailwindcss/src/index.ts:260
} else if (node.params.includes('*')) {
throw new Error(
`\`@utility ${node.params}\` defines an invalid utility name. The dynamic portion marked by \`-*\` must appear once at the end.`,
)
}
}
throw new Error(
`\`@utility ${node.params}\` defines an invalid utility name. Utilities should be alphanumeric and start with a lowercase letter.`,
)
}
customUtilities.push(utility)
}
// Collect paths from `@source` at-rules
if (node.name === '@source') {
if (node.nodes.length > 0) {
throw new Error('`@source` cannot have a body.')
}
if (ctx.parent !== null) {
throw new Error('`@source` cannot be nested.')
}
let not = false
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()View on GitHub (pinned to 16e94cbf7f)
Solutions
- Remove the body block — keep `@source` as a single statement ending with `;`.
- If you meant to define a custom utility, use `@utility name { ... }` instead.
- If you meant to register a custom variant with a body, use `@custom-variant name { ... }`.
Example fix
/* before */
@source "./src/**/*.html" {
/* ... */
}
/* after */
@source "./src/**/*.html"; Defensive patterns
Strategy: validation
Validate before calling
// Fail any @source that carries a body.
import postcss from 'postcss'
function validateSourceHasNoBody(css: string): string[] {
const errors: string[] = []
postcss.parse(css).walkAtRules('@source', (rule) => {
if (rule.nodes.length > 0) {
errors.push(`@source ${rule.params} must not have a body`)
}
})
return errors
} Prevention
- Remember `@source` is a statement, not a block — always terminate with `;`.
- Add an editor snippet that inserts `@source "...";` without a body.
- Lint for at-rules whose names are statement-only but contain nodes.
When it happens
Trigger: Writing `@source "./src/**/*.html" { color: red; }` or any `@source ... { ... }` with a body block.
Common situations: Confusing `@source` (file globs for candidate scanning) with `@utility`/`@variant` (which have bodies); editor auto-completing a `{ }` block after the at-rule.
Related errors
- `@source` cannot be nested.
- `@source` paths must be quoted.
- `@custom-variant ${name}` cannot have both a selector and a
- `@theme` blocks must only contain custom properties or `@key
- The prefix "${resolvedConfig.prefix}" is invalid. Prefixes m
AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12).
Data as JSON: /api/errors/78a65df614b778c6.
Report an issue: GitHub.