{"record":{"id":"759973ad19726ca6","repo":"denoland/deno","slug":"file-not-found","errorCode":null,"errorMessage":"File not found","messagePattern":"File not found","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"runtime/subprocess_windows/src/process.rs","lineNumber":606,"sourceCode":"  let path = child_paths\n    .map(|p| p.encode_wide().chain(Some(0)).collect::<Vec<_>>())\n    .or_else(|| {\n      // PATH not found in provided environment, get system PATH\n      std::env::var_os(\"PATH\")\n        .map(|p| p.encode_wide().chain(Some(0)).collect::<Vec<_>>())\n    });\n\n  // Create and set up stdio\n  let child_stdio_buffer = uv_stdio_create(options)?;\n\n  // Search for the executable\n  let Some(application_path) = search_path(\n    application.as_slice_no_nul(),\n    cwd.as_slice_no_nul(),\n    path.as_deref(),\n    options.flags,\n  ) else {\n    return Err(std::io::Error::new(\n      std::io::ErrorKind::NotFound,\n      \"File not found\",\n    ));\n  };\n\n  // Create command line arguments\n  let args: Vec<&OsStr> = options.args.iter().map(|s| s.as_ref()).collect();\n  let verbatim_arguments =\n    (options.flags & uv_process_flags::WindowsVerbatimArguments) != 0;\n\n  let has_bat_extension = |program: &[u16]| {\n    // lifted from https://github.com/rust-lang/rust/blob/bc1d7273dfbc6f8a11c0086fa35f6748a13e8d3c/library/std/src/sys/process/windows.rs#L284\n    // Copyright The Rust Project Contributors - MIT\n    matches!(\n      // Case insensitive \"ends_with\" of UTF-16 encoded \".bat\" or \".cmd\"\n      program.len().checked_sub(4).and_then(|i| program.get(i..)),\n      Some(\n        [46, 98 | 66, 97 | 65, 116 | 84] | [46, 99 | 67, 109 | 77, 100 | 68]","sourceCodeStart":588,"sourceCodeEnd":624,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/runtime/subprocess_windows/src/process.rs#L588-L624","documentation":"Before CreateProcessW runs, Deno locates the executable with search_path(), using the child's cwd and the PATH from the child environment (or an overridden one) plus Windows extension rules. If no matching executable is found, spawn fails with ErrorKind::NotFound 'File not found', mirroring libuv behavior on Windows.","triggerScenarios":"new Deno.Command(\"tool\").spawn() on Windows where tool / tool.exe / tool.cmd / tool.bat is not on PATH; passing a custom env object that omits PATH so the lookup has nothing to search; a misspelled program or wrong extension; an incorrect cwd option.","commonSituations":"The dependency (git, ffmpeg, magick) is not installed on Windows; replacing env with a literal object and losing PATH; CI or service accounts with a minimal PATH; Unix-first scripts assuming extension-less binary lookup.","solutions":["When passing a custom env, merge it with the parent's: env: { ...Deno.env.toObject(), ...overrides }","Use an absolute path to the executable, including the .exe/.cmd extension on Windows","Install the dependency or add its directory to PATH before spawning","Catch Deno.errors.NotFound and report which program and PATH were used"],"exampleFix":"// before - custom env drops PATH, executable lookup fails\nconst c = new Deno.Command(\"ffmpeg\", { env: { FOO: \"1\" } });\n\n// after - keep PATH while overriding only what you need\nconst c = new Deno.Command(\"ffmpeg\", {\n  env: { ...Deno.env.toObject(), FOO: \"1\" },\n});","handlingStrategy":"try-catch","validationCode":"function findOnPath(prog: string, path = Deno.env.get(\"PATH\") ?? \"\"): string | null {\n  for (const dir of path.split(\";\")) {\n    for (const ext of [\"\", \".exe\", \".cmd\", \".bat\"]) {\n      const p = `${dir}/${prog}${ext}`;\n      try {\n        if (Deno.statSync(p).isFile) return p;\n      } catch { /* keep scanning */ }\n    }\n  }\n  return null;\n}\nconst exe = findOnPath(prog); // null -> fail with a clear message before spawn","typeGuard":null,"tryCatchPattern":"try {\n  const child = cmd.spawn();\n} catch (err) {\n  if (err instanceof Deno.errors.NotFound) {\n    console.error(`\"${prog}\" not found on PATH`);\n    Deno.exit(1);\n  }\n  throw err;\n}","preventionTips":["Merge custom env with Deno.env.toObject() so PATH survives overrides","Prefer absolute executable paths (with extension) on Windows","Log the effective PATH when a spawn fails to speed up diagnosis"],"tags":["windows","subprocess","path","not-found","environment-variables"],"backgroundTag":"command-not-found","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","contentChangedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}