tailwindlabs/tailwindcss · error · Error
The path given to `source(…)` must be a directory but got `s
Error message
The path given to `source(…)` must be a directory but got `source(${basePath})` instead. What it means
The Turbopack plugin validates that every `source(…)` path resolves to an existing directory. It stats the resolved `base+pattern` path; if `statSync` succeeds but the entry is not a directory (e.g. it points at a file), it throws. Notably, `ENOENT` is swallowed — a not-yet-existing directory is tolerated so that source paths can be created during the build.
Source
Thrown at packages/@tailwindcss-turbopack/src/index.ts:248
// Skip negated patterns
if (glob.pattern[0] === '!') continue
// Avoid adding a dependency on the base directory itself
if (glob.pattern === '*' && base === glob.base) {
continue
}
this.addContextDependency(path.resolve(glob.base))
}
// Validate that source(...) paths are directories
let root = compiler.root
if (root !== 'none' && root !== null) {
let basePath = normalizePath(path.resolve(root.base, root.pattern))
try {
let stats = fs.statSync(basePath)
if (!stats.isDirectory()) {
throw new Error(
`The path given to \`source(…)\` must be a directory but got \`source(${basePath})\` instead.`,
)
}
} catch (err) {
if ((err as NodeJS.ErrnoException).code !== 'ENOENT') {
throw err
}
// Directory doesn't exist yet, which is fine
}
}
DEBUG && I.end('Register dependency messages')
}
DEBUG && I.start('Build utilities')
let css = compiler.build([...context.candidates])
DEBUG && I.end('Build utilities')
// Optionally optimize the outputView on GitHub (pinned to 16e94cbf7f)
Solutions
- Change the `source(…)` value to a directory path, or append a glob (e.g. `./src/**/*.tsx`) so the literal prefix is a directory.
- If you only want one file, wrap it in a glob like `./src/app.{tsx,ts}`.
- Ensure no file occupies the directory path you intend to use.
Example fix
/* before */ @source "./src/App.tsx"; /* after */ @source "./src/**/*.tsx";
Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from 'node:fs'
function assertSourceIsDir(pattern: string, base: string) {
const p = path.resolve(base, pattern)
try {
if (statSync(p).isFile()) throw new Error(`source(${pattern}) is a file, not a directory`)
} catch (e) { if ((e as NodeJS.ErrnoException).code !== 'ENOENT') throw e }
} Type guard
function isGlobPattern(s: string): boolean { return /[*{}]/.test(s) } Prevention
- Use directory paths or globs in source(), never bare file paths.
- Confirm no file shadows an intended directory name.
- Let the literal prefix of a glob be a real directory.
When it happens
Trigger: `source("./src/app.tsx")` where the path is a file rather than a directory, or `source("./package.json")`. `fs.statSync(basePath)` returns stats, `isDirectory()` is false, and index.ts:248 throws. (If the path does not exist at all, no error is thrown.)
Common situations: Pointing `@source` at a single file path instead of a directory/glob, or a path that used to be a directory but was replaced by a file of the same name.
Related errors
- The `source(${compiler.root.pattern})` does not exist or is
- The path given to `source(…)` must be a directory but got `s
- The path given to `source(…)` must be a directory but got `s
- The browser build does not support @import for "${id}"
- <stdin> has no metadata
AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12).
Data as JSON: /api/errors/a797915eff1d684a.
Report an issue: GitHub.