{"record":{"id":"91cb0554150f2958","repo":"ducaale/xh","slug":"cannot-build-a-multipart-request-body-from-stdin","errorCode":null,"errorMessage":"Cannot build a multipart request body from stdin","messagePattern":"Cannot build a multipart request body from stdin","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main.rs","lineNumber":120,"sourceCode":"        return Ok(ExitCode::SUCCESS);\n    }\n\n    if args.curl {\n        to_curl::print_curl_translation(args)?;\n        return Ok(ExitCode::SUCCESS);\n    }\n\n    let (mut headers, headers_to_unset) = args.request_items.headers()?;\n    let url = url_with_query(args.url, &args.request_items.query()?);\n    log::debug!(\"Complete URL: {url}\");\n\n    let use_stdin = !(args.ignore_stdin || io::stdin().is_terminal() || test_pretend_term());\n\n    let body = if use_stdin {\n        if !args.request_items.is_body_empty() {\n            if args.multipart {\n                // Multipart bodies are never \"empty\", so we can get here without request items\n                return Err(anyhow!(\"Cannot build a multipart request body from stdin\"));\n            } else {\n                return Err(anyhow!(\n                    \"Request body (from stdin) and request data (key=value) cannot be mixed. \\\n                    Pass --ignore-stdin to ignore standard input.\"\n                ));\n            }\n        }\n        if args.raw.is_some() {\n            return Err(anyhow!(\n                \"Request body from stdin and --raw cannot be mixed. \\\n                Pass --ignore-stdin to ignore standard input.\"\n            ));\n        }\n        let mut buffer = Vec::new();\n        io::stdin().read_to_end(&mut buffer)?;\n        Body::Raw(buffer)\n    } else if let Some(raw) = args.raw {\n        Body::Raw(raw.into_bytes())","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/ducaale/xh/blob/2404aceecc08b0b2d100fedc96f57745cd5904dc/src/main.rs#L102-L138","documentation":"When stdin is piped into the CLI while --multipart is set, the body would have to come from stdin, but a multipart body cannot be constructed from raw stdin bytes together with the multipart form framing. The CLI refuses rather than producing a broken request.","triggerScenarios":"run() detects use_stdin (stdin piped and not --ignore-stdin), args.request_items.is_body_empty() is false or multipart forces entry, and args.multipart is true; then this error is returned before building the request.","commonSituations":"Piping a file into the command while also passing --multipart; scripting usage like `cat file | xh --multipart POST url`; forgetting --ignore-stdin in CI where stdin is a pipe.","solutions":["Pass the file as a request item (e.g. file_field@path) instead of piping it via stdin.","Add --ignore-stdin so the CLI ignores the piped stdin and builds the multipart body from request items only.","Redirect stdin from the terminal or run in an interactive shell.","Drop --multipart if you actually want a raw stdin body."],"exampleFix":"// before\ncat data.bin | xh --multipart POST example.org\n// after\nxh --multipart POST example.org file@data.bin","handlingStrategy":"validation","validationCode":"if !std::io::stdin().is_terminal() && !ignore_stdin && multipart_enabled {\n    eprintln!(\"stdin is piped; pass --ignore-stdin or use field@file for multipart\");\n    std::process::exit(2);\n}","typeGuard":null,"tryCatchPattern":"match run(args) {\n    Err(e) if e.to_string().contains(\"multipart request body from stdin\") => {\n        eprintln!(\"tip: use --ignore-stdin or pass files as request items\");\n    }\n    other => other,\n}","preventionTips":["In scripts, always pass --ignore-stdin unless you intend to pipe a body.","Send multipart files via field@path request items, never via stdin pipes.","Redirect stdin from /dev/null in CI jobs.","Remember --multipart changes what an 'empty' body means."],"tags":["cli","stdin","multipart","http"],"backgroundTag":"mutually-exclusive-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"}