rust-lang/cargo · error · io::Error
argument for argfile contains newlines
Error message
argument for argfile contains newlines: `{arg}` What it means
In the same argfile-building loop, after confirming each argument is valid UTF-8, Cargo checks `arg.contains('\n')`. Because the argfile format writes exactly one argument per line (`writeln!(buf, "{arg}")`), an embedded newline would split a single argument across lines and corrupt parsing. Any argument containing a newline triggers this `io::Error` (kind `Other`).
Solutions
- Strip or replace newlines in the argument before passing it to the `ProcessBuilder`.
- Write multiline content to a separate file and pass the file path as the argument instead.
- Encode the argument (e.g. base64 or JSON on a single line) so it contains no newlines.
Example fix
// before
let cfg = "key1=val1\nkey2=val2";
pb.arg(cfg);
// after
let cfg = "key1=val1\nkey2=val2".replace('\n', " ");
pb.arg(cfg); Defensive patterns
Strategy: validation
Validate before calling
fn args_no_newlines(args: &[String]) -> Result<(), String> {
for a in args {
if a.contains('\n') { return Err(format!("arg contains newline: {a:?}")); }
}
Ok(())
}
// call before populating a ProcessBuilder that may use argfile mode Prevention
- Strip newlines from any argument before adding it to a ProcessBuilder.
- Pass multiline content via a file path, not inline.
- Encode binary/multiline data (base64/JSON single-line) before passing as an arg.
When it happens
Trigger: A `ProcessBuilder` argument containing a `\n` byte, materialized into an argfile. For example, a multiline string value, a JSON/document argument with newlines, or a path with an embedded newline (possible on some filesystems).
Common situations: Passing a multiline configuration snippet, script body, or structured payload as a single command-line argument; tooling that embeds raw file contents into an argument; unusual filenames containing newlines.
Related errors
- argument for argfile contains invalid UTF-8 characters
- failed to parse process output
- credential process ` ` failed with status
- no argv[0]
AI-assisted analysis of rust-lang/cargo@42eee92bc9 (2026-08-11).
Data as JSON: /api/errors/05a14b8be4489cc3.
Report an issue: GitHub.
Appendix: source
Thrown at crates/cargo-util/src/process_builder.rs:513
arg.push(tmp.path());
let mut cmd = self.build_command_without_args();
cmd.arg(arg);
tracing::debug!("created argfile at {} for {self}", tmp.path().display());
let cap = self.get_args().map(|arg| arg.len() + 1).sum::<usize>();
let mut buf = Vec::with_capacity(cap);
for arg in &self.args {
let arg = arg.to_str().ok_or_else(|| {
io::Error::new(
io::ErrorKind::Other,
format!(
"argument for argfile contains invalid UTF-8 characters: `{}`",
arg.to_string_lossy()
),
)
})?;
if arg.contains('\n') {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("argument for argfile contains newlines: `{arg}`"),
));
}
writeln!(buf, "{arg}")?;
}
tmp.write_all(&mut buf)?;
Ok((cmd, tmp))
}
/// Builds a command from `ProcessBuilder` for everything but not `args`.
fn build_command_without_args(&self) -> Command {
let mut command = {
let mut iter = self.wrappers.iter().rev().chain(once(&self.program));
let mut cmd = Command::new(iter.next().expect("at least one `program` exists"));
cmd.args(iter);
cmd
};View on GitHub (pinned to 42eee92bc9)