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 output

View on GitHub (pinned to 16e94cbf7f)

Solutions

  1. Change the `source(…)` value to a directory path, or append a glob (e.g. `./src/**/*.tsx`) so the literal prefix is a directory.
  2. If you only want one file, wrap it in a glob like `./src/app.{tsx,ts}`.
  3. 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

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


AI-assisted analysis of tailwindlabs/tailwindcss@16e94cbf7f (2026-08-12). Data as JSON: /api/errors/a797915eff1d684a. Report an issue: GitHub.