denoland/deno · error

Failed to spawn '{}': No such cwd '{}'

Error message

Failed to spawn '{}': No such cwd '{}'

What it means

Deno's process spawn wrapper (ext/process/lib.rs, backing Deno.Command and node:child_process) pre-validates the cwd option against the real filesystem before exec. If the configured working directory does not exist, spawn fails immediately with ErrorKind::NotFound and this message naming the program and the missing path, instead of surfacing an opaque exec error.

Source

Thrown at ext/process/lib.rs:1120

  // `ChildResource` implements its own `Drop` that kills the child process
  // by PID when `kill_on_drop` is true. This allows `unref()` to disable
  // kill-on-drop, so the child can outlive the parent (matching Node.js
  // semantics for `child_process.unref()`).

  let child = match command.spawn() {
    Ok(child) => child,
    Err(err) => {
      #[cfg(not(windows))]
      let command = command.as_std();
      let command_name = command.get_program().to_string_lossy();

      if let Some(cwd) = command.get_current_dir() {
        // launching a sub process always depends on the real
        // file system so using these methods directly is ok
        #[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 '{}'",

View on GitHub (pinned to a961cdec3b)

Solutions

  1. Create the directory before spawning: await mkdir(cwd, { recursive: true }).
  2. Resolve cwd to an absolute path (path.resolve) so it does not depend on the parent's current directory.
  3. Validate with fs.existsSync/statSync().isDirectory() before spawn and fail fast with a clear message.
  4. If the directory was deleted by a build step, fix the ordering so spawn happens after the artifact dir exists.

Example fix

// before
const cmd = new Deno.Command("cargo", { cwd: "./target/bench" }); // ENOENT if dir absent

// after
import { ensureDir } from "jsr:@std/fs";
await ensureDir("./target/bench");
const cmd = new Deno.Command("cargo", { cwd: await Deno.realPath("./target/bench") });
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from "node:fs";
import { resolve } from "node:path";
const cwd = resolve(opts.cwd ?? ".");
const st = statSync(cwd, { throwIfNoEntry: false });
if (!st) throw new Error(`cwd does not exist: ${cwd}`);
if (!st.isDirectory()) throw new Error(`cwd is not a directory: ${cwd}`);

Type guard

import { statSync } from "node:fs";
const isUsableCwd = (p: string): p is string => { const st = statSync(p, { throwIfNoEntry: false }); return !!st?.isDirectory(); };

Try / catch

try { new Deno.Command(prog, { cwd }); } catch (e) { if (/No such cwd/.test(String(e))) throw new Error(`configured cwd missing — create it first: ${cwd}`); throw e; }

Prevention

When it happens

Trigger: new Deno.Command(prog, { cwd }) or child_process.spawn(prog, { cwd }) where cwd points to a nonexistent path: deleted directory, wrong relative path resolved against the parent's cwd, typo in config, or a path valid in dev but absent in the deployed image.

Common situations: Docker images missing the directory the app assumes; relative cwd like './build' when the process starts from a different directory; directories removed by a clean step; configs pointing at another machine's layout.

Related errors


AI-assisted analysis of denoland/deno@a961cdec3b (2026-08-20). Data as JSON: /api/errors/583a222903b3b2f8. Report an issue: GitHub.