ducaale/xh · error
Can't read request from multiple files
Error message
Can't read request from multiple files
What it means
xh refuses to build a request body when more than one file would supply it. In body_from_file, multipart file items and the -f single-file body path all feed the single `body` variable; a second file item finds body already Some and aborts, because an HTTP request body can only have one source here.
Solutions
- Use only one file for the request body; remove the extra file argument
- If multiple parts are needed, use multipart form syntax: -f or key=value@file items instead of a bare body file
- Combine the files into one file first, or use stdin (e.g. `cat a b | xh POST url`)
- Check the constructed CLI/script for duplicated --body-file/@file arguments
Example fix
// before xh POST example.org/upload @part1.bin @part2.bin // after xh -f POST example.org/upload part1@part1.bin part2@part2.bin
Defensive patterns
Strategy: validation
Validate before calling
// count file-sourced body parts before invoking
let file_args = std::env::args().filter(|a| a == "@" || a.starts_with('@')).count();
if file_args > 1 { eprintln!("pass at most one body file; use -f key@file for parts"); std::process::exit(2); } Try / catch
match result {
Err(e) if e.to_string().contains("multiple files") => eprintln!("Use -f key=value@file for multiple parts"),
Err(e) => return Err(e),
Ok(v) => Ok(v),
} Prevention
- Use at most one bare body file per request
- Use multipart form items (key@file) when uploading several files
- Review generated scripts for duplicated @file/--body-file flags
When it happens
Trigger: Passing multiple standalone file arguments (or a request-items file entry after another file) so that `body` is already Some(Body::File{..}) when the next file is processed, e.g. `xh POST url @a.json @b.json` or combining a body file with a form file item.
Common situations: Users mimicking curl's multiple @file behavior; scripts appending extra file arguments by mistake; confusion between `-f` form fields (multiple allowed) and a single request body file.
Related errors
- Cannot build a multipart request body from stdin
- Request body (from stdin) and request data (key=value)…
- JSON values are not supported in multipart fields
- Request body (from a file) and request data (key=value)…
- JSON values are not supported in multipart fields
AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13).
Data as JSON: /api/errors/369d28d51614af24.
Report an issue: GitHub.
Appendix: source
Thrown at src/request_items.rs:429
for item in self.items {
match item {
RequestItem::DataField { .. }
| RequestItem::JsonField(..)
| RequestItem::DataFieldFromFile { .. }
| RequestItem::JsonFieldFromFile(..) => {
return Err(anyhow!(
"Request body (from a file) and request data (key=value) cannot be mixed."
));
}
RequestItem::FormFile {
key,
file_name,
file_type,
file_name_header,
} => {
assert!(key.is_empty());
if body.is_some() {
return Err(anyhow!("Can't read request from multiple files"));
}
body = Some(Body::File {
file_type: file_type
.as_deref()
.or_else(|| mime_guess::from_path(&file_name).first_raw())
.map(HeaderValue::from_str)
.transpose()?,
file_name: expand_tilde(file_name),
file_name_header,
});
}
RequestItem::HttpHeader(..)
| RequestItem::HttpHeaderFromFile(..)
| RequestItem::HttpHeaderToUnset(..)
| RequestItem::UrlParam(..)
| RequestItem::UrlParamFromFile(..) => {}
}
}View on GitHub (pinned to 2404aceecc)