ducaale/xh · error
Request body (from a file) and request data (key=value)…
Error message
Request body (from a file) and request data (key=value) cannot be mixed.
What it means
A request body can come either from a file/stdin (`@file` or redirect syntax) or from key=value request items — never both, since there is only one body. `body_from_file` detects any `DataField`, `JsonField`, `DataFieldFromFile`, or `JsonFieldFromFile` item alongside the file body and returns this error to force the user to pick one source.
Solutions
- Remove the `key=value`/`key:=value` items if the file (or stdin) should be the whole body.
- Drop the `@file` body and express everything as request items if fields are what you want.
- Move non-body data to the correct syntax: query params use `key==value`, headers use `Header:value`.
Example fix
// before xh POST :8080 @data.json name=John // after xh POST :8080 @data.json
Defensive patterns
Strategy: validation
Validate before calling
# guard: don't mix @file/stdin body with data items
if { echo "$args" | grep -qE '(^| )@'; } && echo "$args" | grep -qE '[A-Za-z0-9_]+(=|:=)'; then
echo 'cannot mix file body with key=value items'; exit 1
fi Try / catch
match result {
Err(e) if e.to_string().contains("cannot be mixed") => {
eprintln!("choose either a file body or request items, not both");
}
other => other?,
} Prevention
- Use == for query params and Header:value for headers instead of body fields.
- Decide the body source (file vs items) at script design time.
- Never pipe stdin body while also passing key=value items.
When it happens
Trigger: Running `xh POST :8080 @data.json name=John` (file body plus `=`/`:=` items), or `cat body.json | xh POST :8080 key=value` — stdin body combined with data items.
Common situations: Appending query/auth-looking items that should have been `==` (query params) or headers (`Header:value`) but were typed as body fields; scripting where a body file and generated fields are both present.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- Request body (from stdin) and request data (key=value)…
- Cannot build a multipart request body from stdin
- Request body from stdin and --raw cannot be mixed. Pass…
- Message signature components require both…
- JSON values are not supported in Form fields
AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13).
Data as JSON: /api/errors/133ff5fe02b3f382.
Report an issue: GitHub.
Appendix: source
Thrown at src/request_items.rs:417
fn body_from_file(self) -> Result<Body> {
let mut body = None;
if self
.items
.iter()
.any(|item| matches!(item, RequestItem::FormFile {key, ..} if !key.is_empty()))
{
return Err(anyhow!(
"Can't use file fields in JSON mode (perhaps you meant --form?)"
));
}
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)View on GitHub (pinned to 2404aceecc)