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 Vite plugin validates each `source(…)` path resolves to a directory. It stats `basePath` and, if the stat either fails or the entry is not a directory, throws. Unlike the Turbopack/Webpack variants, the Vite version treats both not-found and not-a-directory as failure (`isDir` is false on rejection).
Source
Thrown at packages/@tailwindcss-vite/src/index.ts:667
}
// Ensure relative is a posix style path since we will merge it with the
// glob.
relative = normalizePath(relative)
addWatchFile(path.posix.join(relative, glob.pattern))
let root = this.compiler.root
if (root !== 'none' && root !== null) {
let basePath = normalizePath(path.resolve(root.base, root.pattern))
let isDir = await fs.stat(basePath).then(
(stats) => stats.isDirectory(),
() => false,
)
if (!isDir) {
throw new Error(
`The path given to \`source(…)\` must be a directory but got \`source(${basePath})\` instead.`,
)
}
}
}
DEBUG && I.end('Register dependency messages')
}
DEBUG && I.start('Build CSS')
let code = this.compiler.build([...this.candidates])
DEBUG && I.end('Build CSS')
DEBUG && I.start('Build Source Map')
let map = this.enableSourceMaps ? toSourceMap(this.compiler.buildSourceMap()).raw : undefined
DEBUG && I.end('Build Source Map')
return {
code,View on GitHub (pinned to 16e94cbf7f)
Solutions
- Point `source(…)` at a directory or use a glob whose literal prefix is a directory.
- Ensure the directory exists at build/dev start time (create it or order your scripts so generators run first).
- Avoid pointing `@source` at individual files.
Example fix
/* before */
@source "./src/main.tsx";
/* after */
@source "./src/**/*.{ts,tsx}"; Defensive patterns
Strategy: validation
Validate before calling
import { stat } from 'node:fs/promises'
async function assertSourceDir(pattern: string, base: string) {
const p = path.resolve(base, pattern)
const isDir = await stat(p).then(s => s.isDirectory()).catch(() => false)
if (!isDir) throw new Error(`source(${pattern}) must resolve to an existing directory: ${p}`)
} Try / catch
try {
await build()
} catch (e) {
if (/source\(.*\) must be a directory/.test((e as Error).message)) {
// point source() at a directory or fix the glob
}
throw e
} Prevention
- Use directory paths or globs in source(); never bare files.
- Ensure source directories exist at dev/build start.
- Order build scripts so generated dirs exist before Vite runs.
When it happens
Trigger: `source("./src/index.html")` pointing at a file, or `source("./does-not-exist")`. `fs.stat(basePath)` rejects or returns a non-directory, `isDir` is false, and index.ts:667 throws.
Common situations: Pointing `@source` at a file instead of a directory/glob, a source directory deleted during dev, or a path that is only present after a generate step that hasn't run.
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/69d928313a0a2c5b.
Report an issue: GitHub.