parcel-bundler/parcel · error · ThrowableDiagnostic
${path.relative(process.cwd(), source)} is not a file.
Error message
${path.relative(process.cwd(), source)} is not a file. What it means
Thrown by assertFile() when fs.stat(source) succeeds but stat.isFile() returns false — the path exists but is a directory (or a socket/device). Parcel shows a code frame in package.json at the source value so the developer knows which field points at a non-file.
Source
Thrown at packages/core/core/src/requests/EntryRequest.js:133
filePath: pkgFilePath,
codeHighlights: generateJSONCodeHighlights(contents, [
{
key: keyPath,
type: 'value',
},
]),
},
],
hints: alternatives.map(r => {
return md`Did you mean '__${r}__'?`;
}),
},
});
}
if (!stat.isFile()) {
let contents = await fs.readFile(pkgFilePath, 'utf8');
throw new ThrowableDiagnostic({
diagnostic: {
origin: '@parcel/core',
message: md`${path.relative(process.cwd(), source)} is not a file.`,
codeFrames: [
{
filePath: pkgFilePath,
codeHighlights: generateJSONCodeHighlights(contents, [
{
key: keyPath,
type: 'value',
},
]),
},
],
},
});
}
}View on GitHub (pinned to 59484858a1)
Solutions
- Change the source path to point at the specific file, not the containing directory.
- If you intended a directory entry, add a package.json with a source field inside that directory instead.
- Verify with ls -la that the path is a regular file, not a directory.
- Check for accidental file-vs-directory name collisions (e.g., a folder named index.html).
Example fix
// before — package.json
{
"source": "src"
}
// after
{
"source": "src/index.html"
} Defensive patterns
Strategy: validation
Validate before calling
const fs = require('fs');
const path = require('path');
function validateSourceIsFile(pkgPath) {
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
const source = Array.isArray(pkg.source) ? pkg.source[0] : pkg.source;
if (!source) return;
const full = path.join(path.dirname(pkgPath), source);
const stat = fs.statSync(full);
if (!stat.isFile()) {
throw new Error(`Source "${source}" is a ${stat.isDirectory() ? 'directory' : 'non-file'}, expected a file.`);
}
} Prevention
- Always specify the full file path (with extension) in source, not a directory.
- Verify source targets with ls -la in a prebuild check.
- Avoid naming a directory the same as an intended entry file.
When it happens
Trigger: Called from resolveEntry() after stat() resolves successfully. The path path.join(entry, relativeSource) resolves to a directory or special file rather than a regular file, so stat.isFile() is false.
Common situations: source field points to a folder name instead of a file inside it (e.g. "src" instead of "src/index.html"); accidentally created a directory with the same name as the intended entry file; pointing source at a node_modules package directory rather than its main file.
Related errors
- ${path.relative(process.cwd(), source)} does not exist.
- Could not find entry: ${entry}
- Expected package.json file in ${rootDir}
- Entry ${entry} does not exist
- Unknown entry: ${entry}
AI-assisted analysis of parcel-bundler/parcel@59484858a1 (2026-08-13).
Data as JSON: /api/errors/2bc190e4ff2ed5eb.
Report an issue: GitHub.