{"record":{"id":"133ff5fe02b3f382","repo":"ducaale/xh","slug":"request-body-from-a-file-and-request-data-key-value-cannot","errorCode":null,"errorMessage":"Request body (from a file) and request data (key=value) cannot be mixed.","messagePattern":"Request body \\(from a file\\) and request data \\(key=value\\) cannot be mixed\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/request_items.rs","lineNumber":417,"sourceCode":"\n    fn body_from_file(self) -> Result<Body> {\n        let mut body = None;\n        if self\n            .items\n            .iter()\n            .any(|item| matches!(item, RequestItem::FormFile {key, ..} if !key.is_empty()))\n        {\n            return Err(anyhow!(\n                \"Can't use file fields in JSON mode (perhaps you meant --form?)\"\n            ));\n        }\n        for item in self.items {\n            match item {\n                RequestItem::DataField { .. }\n                | RequestItem::JsonField(..)\n                | RequestItem::DataFieldFromFile { .. }\n                | RequestItem::JsonFieldFromFile(..) => {\n                    return Err(anyhow!(\n                        \"Request body (from a file) and request data (key=value) cannot be mixed.\"\n                    ));\n                }\n                RequestItem::FormFile {\n                    key,\n                    file_name,\n                    file_type,\n                    file_name_header,\n                } => {\n                    assert!(key.is_empty());\n                    if body.is_some() {\n                        return Err(anyhow!(\"Can't read request from multiple files\"));\n                    }\n                    body = Some(Body::File {\n                        file_type: file_type\n                            .as_deref()\n                            .or_else(|| mime_guess::from_path(&file_name).first_raw())\n                            .map(HeaderValue::from_str)","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/ducaale/xh/blob/2404aceecc08b0b2d100fedc96f57745cd5904dc/src/request_items.rs#L399-L435","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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`."],"exampleFix":"// before\nxh POST :8080 @data.json name=John\n// after\nxh POST :8080 @data.json","handlingStrategy":"validation","validationCode":"# guard: don't mix @file/stdin body with data items\nif { echo \"$args\" | grep -qE '(^| )@'; } && echo \"$args\" | grep -qE '[A-Za-z0-9_]+(=|:=)'; then\n  echo 'cannot mix file body with key=value items'; exit 1\nfi","typeGuard":null,"tryCatchPattern":"match result {\n    Err(e) if e.to_string().contains(\"cannot be mixed\") => {\n        eprintln!(\"choose either a file body or request items, not both\");\n    }\n    other => other?,\n}","preventionTips":["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."],"tags":["http","request-body","cli","conflict"],"backgroundTag":"conflicting-config-options","analyzedSha":"2404aceecc08b0b2d100fedc96f57745cd5904dc","analyzedAt":"2026-09-13T19:13:33.814Z","contentChangedAt":"2026-09-13T19:13:33.814Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}