vitest-dev/vitest · error · TypeError

Unexpected file type

Error message

Unexpected file type: ${file}

What it means

After resolving a `projects` string entry, `statSync(file)` returned a stats object that is neither a regular file nor a directory (e.g. a FIFO, socket, character/block device, or broken symlink). The source marks this branch `// should never happen` for normal filesystem usage, so hitting it usually indicates an unusual entry in the project tree.

Solutions

  1. Inspect the offending path with `ls -l` / `stat` and identify what type it is.
  2. Remove or replace the special file with a real config file or directory.
  3. If it reproduces on a normal file, file a Vitest issue with the stat details.
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from 'node:fs'
function assertProjectsEntryIsFileOrDir(file: string) {
  const s = statSync(file)
  if (!s.isFile() && !s.isDirectory()) {
    throw new Error(`projects entry '${file}' is neither a file nor a directory (got mode ${s.mode.toString(8)}). Remove the special file.`)
  }
}

Prevention

When it happens

Trigger: A `projects` string resolves to a special filesystem object where `stats.isFile()` and `stats.isDirectory()` are both false.

Common situations: Stray named pipe/socket left in the repo; broken symlink; exotic/filesystem (FUSE) reporting odd stat results.

Related errors


AI-assisted analysis of vitest-dev/vitest@1fa9837ec2 (2026-08-11). Data as JSON: /api/errors/49505c0835318272. Report an issue: GitHub.

Appendix: source

Thrown at packages/vitest/src/node/projects/resolveProjects.ts:1211

            )
          }

          projectsConfigFiles.push(file)
        }
        // user can specify a directory that should be used as a project
        else if (stats.isDirectory()) {
          const configFile = resolveDirectoryConfig(file)
          if (configFile) {
            projectsConfigFiles.push(configFile)
          }
          else {
            const directory = file.at(-1) === '/' ? file : `${file}/`
            nonConfigProjectDirectories.push(directory)
          }
        }
        else {
          // should never happen
          throw new TypeError(`Unexpected file type: ${file}`)
        }
      }
      // if the string is a glob pattern, resolve it later
      // ['./packages/*']
      else {
        projectsGlobMatches.push(stringOption)
      }
    }
    // if the config is inlined, we can resolve it immediately
    else if (typeof definition === 'function') {
      projectsOptions.push(await definition({
        command: 'serve',
        mode: parentViteConfig.mode,
        isPreview: false,
        isSsrBuild: false,
      }))
    }
    // the config is an object or a Promise that returns an object

View on GitHub (pinned to 1fa9837ec2)