{"id":"49505c0835318272","repo":"vitest-dev/vitest","slug":"unexpected-file-type-file","errorCode":null,"errorMessage":"Unexpected file type: ${file}","messagePattern":"Unexpected file type: (.+?)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/vitest/src/node/projects/resolveProjects.ts","lineNumber":1014,"sourceCode":"            )\n          }\n\n          projectsConfigFiles.push(file)\n        }\n        // user can specify a directory that should be used as a project\n        else if (stats.isDirectory()) {\n          const configFile = resolveDirectoryConfig(file)\n          if (configFile) {\n            projectsConfigFiles.push(configFile)\n          }\n          else {\n            const directory = file.at(-1) === '/' ? file : `${file}/`\n            nonConfigProjectDirectories.push(directory)\n          }\n        }\n        else {\n          // should never happen\n          throw new TypeError(`Unexpected file type: ${file}`)\n        }\n      }\n      // if the string is a glob pattern, resolve it later\n      // ['./packages/*']\n      else {\n        projectsGlobMatches.push(stringOption)\n      }\n    }\n    // if the config is inlined, we can resolve it immediately\n    else if (typeof definition === 'function') {\n      projectsOptions.push(await definition({\n        command: 'serve',\n        mode: parentViteConfig.mode,\n        isPreview: false,\n        isSsrBuild: false,\n      }))\n    }\n    // the config is an object or a Promise that returns an object","sourceCodeStart":996,"sourceCodeEnd":1032,"githubUrl":"https://github.com/vitest-dev/vitest/blob/d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09/packages/vitest/src/node/projects/resolveProjects.ts#L996-L1032","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the path with ls -l and file <path> to see what type of object it is.","Replace the special file with a real config file or directory.","Remove the entry from the projects array if it was a mistake.","If reproducible, report it - the code comment says this should never happen."],"exampleFix":"// before: projects: ['/dev/fifo'] resolves to a FIFO\n// after: projects: ['./vitest.config.ts'] (a real file)","handlingStrategy":"validation","validationCode":"import { statSync } from 'node:fs'\nconst s = statSync(file)\nif (!s.isFile() && !s.isDirectory()) throw new Error(`'${file}' is neither a file nor a directory (type flags: ${s.mode.toString(8)})`)","typeGuard":"function isRegularFileOrDir(file: string): boolean {\n  const s = statSync(file)\n  return s.isFile() || s.isDirectory()\n}","tryCatchPattern":null,"preventionTips":["Don't point projects at special files (FIFOs, devices, sockets).","Inspect suspicious paths with ls -l / file before referencing them.","Treat this error as a signal of a misconfigured or corrupted path."],"tags":["projects","filesystem","unexpected","internal","edge-case"],"analyzedSha":"d568f8ce3739b532d5bf2c1ee1e45e8a8a473d09","analyzedAt":"2026-08-03T20:23:56.861Z","schemaVersion":2}