ducaale/xh · warning
-I/--head is incompatible with sending data. Consider…
Error message
-I/--head is incompatible with sending data. Consider omitting -h/--headers.
What it means
xh's to_curl translation emits `curl -I` (head request) when the request was constructed as a HEAD (typically via -h/--headers), but the request also carries a body or non-GET method that curl's -I cannot express alongside sent data. Rather than silently producing a wrong curl command, translate() warns that -I/--head is incompatible and suggests omitting -h/--headers.
Solutions
- Omit -h/--headers so the request keeps its intended method and body
- If you truly want a HEAD request, drop the body flags (-d/--data/--raw)
- Replace -h with an explicit -X HEAD only if no data is being sent
- If you meant to send a header in curl, remember xh uses -H for headers and -h means HEAD
Example fix
# before xh --curl -h POST example.org/api key=value # after (drop -h to send the POST body) xh --curl POST example.org/api key=value
Defensive patterns
Strategy: validation
Validate before calling
# Reject the combination before running if echo "$args" | grep -qe '(^| )-h( |$)' && echo "$args" | grep -qe '(^| )-d( |$)'; then echo "error: -h/--headers (HEAD) cannot be combined with a request body"; exit 1 fi
Type guard
fn is_head_with_body(args: &XhArgs) -> bool {
args.headers && args.request_items.body_items().next().is_some()
} Prevention
- Remember xh's -h means HEAD, not 'send header' (that is -H)
- Never pair -h/--headers with -d/--data or --raw
- Use explicit -X POST/PUT when you intend to send a body
- Test generated curl commands with --curl before scripting around them
When it happens
Trigger: Running `xh -h/--headers` (or otherwise forcing a HEAD) on a request that also sends data (POST/PUT with a body) and passing --curl/--curl-long so translate() generates the curl command, where method != GET.
Common situations: Users combining -h (HEAD) with -d/--data or --raw payloads; scripts converting an xh invocation that accidentally had both -h and a request body into curl; confusion between -h/--headers in xh (HEAD) and -h (header) in curl.
Understand the failure class
Background: "mutually exclusive" flag errors: what "can't supply both nx and xx", "--raw is not compatible with -i" and "cannot be used with" mean, and how to fix them — this error's family across 29 libraries.
Related errors
- Invalid UTF-8
- JSON values are not supported in multipart fields
- Inferred port number in --resolve from request URL.
- Ignored
- Using a combination of -X/--request and -L/--location which…
AI-assisted analysis of ducaale/xh@2404aceecc (2026-09-13).
Data as JSON: /api/errors/2dcfba63afeaf5fe.
Report an issue: GitHub.
Appendix: source
Thrown at src/to_curl.rs:280
cmd.opt("-i", "--include");
cmd.opt("-X", "--request");
cmd.arg("OPTIONS");
} else if args.headers {
// The best option for printing just headers seems to be to use -I
// but with an explicit method as an override.
// But this is a hack that actually fails if data is sent.
// See discussion on https://lornajane.net/posts/2014/view-only-headers-with-curl
let method = match args.method {
Some(method) => method,
// unwrap_or_else causes borrowing issues
None => args.request_items.pick_method(),
};
cmd.opt("-I", "--head");
cmd.opt("-X", "--request");
cmd.arg(method.to_string());
if method != Method::GET {
cmd.warn(
"-I/--head is incompatible with sending data. Consider omitting -h/--headers."
.to_string(),
);
}
} else if let Some(method) = args.method {
cmd.opt("-X", "--request");
cmd.arg(method.to_string());
} else {
// We assume that curl's automatic detection of when to do a POST matches
// ours so we can ignore the None case
}
let url = url_with_query(args.url, &args.request_items.query()?);
if url.as_str().contains(['[', ']', '{', '}']) {
cmd.opt("-g", "--globoff")
}
View on GitHub (pinned to 2404aceecc)