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

  1. Omit -h/--headers so the request keeps its intended method and body
  2. If you truly want a HEAD request, drop the body flags (-d/--data/--raw)
  3. Replace -h with an explicit -X HEAD only if no data is being sent
  4. 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

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


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)