vitest-dev/vitest · error · TypeError

Unexpected file type: ${file}

Error message

Unexpected file type: ${file}

What it means

resolveTestProjectConfigs (resolveProjects.ts:1012-1015) handles string entries that exist on disk as either files (CONFIG_REGEXP-checked) or directories. The else branch fires when statSync reports something that is neither a regular file nor a directory - e.g. a symbolic link to a device, a FIFO/socket, a block/character device. The source comment marks this as 'should never happen' under normal usage.

Source

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

            )
          }

          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 d568f8ce37)

Solutions

  1. Check the path with ls -l and file <path> to see what type of object it is.
  2. Replace the special file with a real config file or directory.
  3. Remove the entry from the projects array if it was a mistake.
  4. If reproducible, report it - the code comment says this should never happen.

Example fix

// before: projects: ['/dev/fifo'] resolves to a FIFO
// after: projects: ['./vitest.config.ts'] (a real file)
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from 'node:fs'
const s = statSync(file)
if (!s.isFile() && !s.isDirectory()) throw new Error(`'${file}' is neither a file nor a directory (type flags: ${s.mode.toString(8)})`)

Type guard

function isRegularFileOrDir(file: string): boolean {
  const s = statSync(file)
  return s.isFile() || s.isDirectory()
}

Prevention

When it happens

Trigger: A projects entry resolves to a special filesystem object: a named pipe, socket, device node, or a broken symlink whose target stat returns a non-file/non-dir type. Essentially unreachable with regular config files.

Common situations: Extremely rare; possible on systems where a symlink points to /dev/null or a FIFO, or in odd container/overlay filesystem layouts; could indicate filesystem corruption or a deliberately weird path.

Related errors


AI-assisted analysis of vitest-dev/vitest@d568f8ce37 (2026-08-03). Data as JSON: /data/errors/49505c0835318272.json. Report an issue: GitHub.