denoland/deno · error
Failed to spawn '{}': cwd is not a directory '{}'
Error message
Failed to spawn '{}': cwd is not a directory '{}' What it means
Companion check to the 'No such cwd' error in Deno's spawn wrapper: the path in cwd exists (the earlier exists() check passed) but is not a directory — typically a regular file. Spawn aborts with ErrorKind::NotFound and this message before attempting exec.
Source
Thrown at ext/process/lib.rs:1135
#[allow(clippy::disallowed_methods, reason = "requires real fs")]
if !cwd.exists() {
return Err(
std::io::Error::new(
std::io::ErrorKind::NotFound,
format!(
"Failed to spawn '{}': No such cwd '{}'",
command_name,
cwd.to_string_lossy()
),
)
.into(),
);
}
#[allow(clippy::disallowed_methods, reason = "requires real fs")]
if !cwd.is_dir() {
return Err(
std::io::Error::new(
std::io::ErrorKind::NotFound,
format!(
"Failed to spawn '{}': cwd is not a directory '{}'",
command_name,
cwd.to_string_lossy()
),
)
.into(),
);
}
}
return Err(ProcessError::SpawnFailed {
command: command.get_program().to_string_lossy().into_owned(),
error: Box::new(err.into()),
});
}
};View on GitHub (pinned to a961cdec3b)
Solutions
- Wrap the intended directory: use path.dirname(filePath) instead of the file path itself.
- statSync the path and require isDirectory() before spawning; fail with the path in the error.
- Delete or rename the stray file if a directory is genuinely expected there and something else created it.
- Add a startup assertion for configured cwd values so misconfiguration is caught at boot.
Example fix
// before
const cwd = import.meta.filename; // a file, not a directory
const child = spawn("git", ["status"], { cwd }); // fails: cwd is not a directory
// after
import { dirname } from "node:path";
const cwd = dirname(fileURLToPath(import.meta.url));
const child = spawn("git", ["status"], { cwd }); Defensive patterns
Strategy: validation
Validate before calling
import { statSync } from "node:fs";
if (statSync(cwd, { throwIfNoEntry: false })?.isDirectory() !== true) throw new Error(`cwd must be a directory: ${cwd}`); Type guard
import { statSync } from "node:fs";
const isDirectoryPath = (p: string): p is `${string}/` => statSync(p, { throwIfNoEntry: false })?.isDirectory() ?? false; Try / catch
try { spawn(prog, args, { cwd }); } catch (e) { if (/cwd is not a directory/.test(String(e))) throw new Error(`cwd points at a file — use path.dirname(): ${cwd}`); throw e; } Prevention
- When you mean 'next to this file', pass path.dirname(fileURLToPath(import.meta.url)), never the file path.
- Run a startup check on every configured cwd: exists AND isDirectory.
- Beware path.join(a, b) where b is a filename — that builds a file path, not a dir.
When it happens
Trigger: Deno.Command/child_process.spawn with cwd set to a file path: pointing cwd at a script or archive instead of its directory, a path where a file shadows an expected directory name, or a symlink target that is a file.
Common situations: Passing __filename or a config file path where the containing directory was intended; a file created at the location a build step was supposed to make a directory; incorrect path joining (path.join vs path.dirname confusion).
Related errors
- Failed to spawn '{}': No such cwd '{}'
- ERR_INVALID_ARG_TYPE
- Unable to construct URL from the path of cwd: {}
- nul byte found in provided data
- Unexpected 'name' field in options, bench name is already pr
AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20).
Data as JSON: /api/errors/14ebc6b4c5b45ba4.
Report an issue: GitHub.