{"record":{"id":"08113aaa4ee9cc1c","repo":"denoland/deno","slug":"nul-byte-found-in-provided-data-08113a","errorCode":null,"errorMessage":"nul byte found in provided data","messagePattern":"nul byte found in provided data","errorType":"exception","errorClass":"ProcessError::Io","httpStatus":null,"severity":"error","filePath":"ext/process/lib.rs","lineNumber":782,"sourceCode":"    }\n    command.args(args.args);\n  }\n\n  #[cfg(unix)]\n  let uid = args.uid;\n  #[cfg(unix)]\n  let gid = args.gid;\n  #[cfg(unix)]\n  let move_cwd_to_pre_exec =\n    should_change_cwd_in_pre_exec(uid, gid, run_env.set_cwd_on_command);\n  // Rust applies built-in uid/gid changes before current_dir, but applies\n  // current_dir before user pre_exec callbacks. Defer it into our callback so\n  // replacing the built-in identity setup preserves uid/gid-before-cwd order.\n  #[cfg(unix)]\n  let pre_exec_cwd = if move_cwd_to_pre_exec {\n    Some(\n      CString::new(run_env.cwd.as_os_str().as_bytes()).map_err(|err| {\n        ProcessError::Io(std::io::Error::new(\n          std::io::ErrorKind::InvalidInput,\n          err,\n        ))\n      })?,\n    )\n  } else {\n    None\n  };\n\n  #[cfg(unix)]\n  if run_env.set_cwd_on_command && !move_cwd_to_pre_exec {\n    command.current_dir(&run_env.cwd);\n  }\n  #[cfg(windows)]\n  if run_env.set_cwd_on_command {\n    command.current_dir(&run_env.cwd);\n  }\n  command.env_clear();","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/denoland/deno/blob/a961cdec3b1948844414ebeecc697dcad76df2d1/ext/process/lib.rs#L764-L800","documentation":"When spawning a subprocess, the cwd path must be converted to a CString for the OS exec. Rust's CString::new rejects any byte sequence containing interior NUL bytes; the resulting error is surfaced as an InvalidInput io error ('nul byte found in provided data') from create_command (reached via op_spawn_child, op_node_spawn_child, op_spawn_sync).","triggerScenarios":"Calling Deno.Command (or Node child_process spawn) with a cwd (or related env path handled by the same path) containing a \\0 character — typically via a programmatically built string or a path read from a source that preserved NUL bytes.","commonSituations":"Paths assembled from binary data or fixed-width buffers with padding NULs; env vars or config values read as byte arrays; deserialized paths that include a terminator NUL.","solutions":["Strip NUL bytes from cwd before spawning: cwd.replaceAll('\\0', '') or truncate at the first NUL.","Validate the cwd string (no '\\u0000') before constructing Deno.Command.","If the path came from a byte buffer, decode with the NUL terminator removed instead of including it."],"exampleFix":"// before\nnew Deno.Command('ls', { cwd: cwdFromBuffer }); // may contain \\0\n// after\nconst cwd = cwdFromBuffer.split('\\u0000')[0];\nnew Deno.Command('ls', { cwd });","handlingStrategy":"validation","validationCode":"function sanitizePath(p) {\n  if (typeof p !== 'string' || p.includes('\\u0000')) {\n    throw new TypeError('Path must not contain NUL bytes');\n  }\n  return p;\n}\nnew Deno.Command(cmd, { cwd: sanitizePath(cwd) });","typeGuard":"function isNulFreePath(p) {\n  return typeof p === 'string' && !p.includes('\\u0000');\n}","tryCatchPattern":"try {\n  const child = new Deno.Command(cmd, { cwd }).spawn();\n} catch (err) {\n  if (String(err.message).includes('nul byte found in provided data')) {\n    // retry with cwd = cwd.split('\\u0000')[0]\n  }\n}","preventionTips":["Decode byte-buffer paths with the NUL terminator stripped before using them as cwd.","Validate cwd/env string paths for '\\u0000' at the boundary where they are read.","Prefer typed string sources (Deno.readTextFile) over raw byte buffers for path inputs."],"tags":["process","spawn","validation"],"backgroundTag":"nul-byte-in-path","analyzedSha":"a961cdec3b1948844414ebeecc697dcad76df2d1","analyzedAt":"2026-09-03T14:18:07.398Z","contentChangedAt":"2026-09-03T14:18:07.398Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}