BoundaryML/baml · error

baml.fetch_as: expected header key to be a valid HTTP header

Error message

baml.fetch_as: expected header key to be a valid HTTP header name, got {}

What it means

Each key in the `headers` map of a baml.HttpRequest must parse as a valid HTTP header name per reqwest's HeaderName rules (token characters, e.g. alphanumeric plus !#$%&'*+-.^_`|~). An invalid key aborts the request build.

Source

Thrown at engine/baml-runtime/src/async_vm_runtime.rs:636

                                                let mut req = match method.as_str() {
                                                    "Get" => client.get(url),
                                                    "Post" => client.post(url),
                                                    "Put" => client.put(url),
                                                    "Patch" => client.patch(url),
                                                    "Delete" => client.delete(url),
                                                    _ => break 'res Err(anyhow!(
                                                        "baml.fetch_as: expected method to be a valid HTTP method, got {}",
                                                        method
                                                    ))
                                                };

                                                if let Some(BamlValue::Map(headers)) = fields.get("headers") {
                                                    let mut header_map = reqwest::header::HeaderMap::new();

                                                    for (k, v) in headers {
                                                        let Ok(key) = reqwest::header::HeaderName::from_str(k) else {
                                                            break 'res Err(anyhow!(
                                                                "baml.fetch_as: expected header key to be a valid HTTP header name, got {}",
                                                                k
                                                            ));
                                                        };

                                                        let Some(value_as_string) = v.as_str() else {
                                                            break 'res Err(anyhow!(
                                                                "baml.fetch_as: expected header value to be a string, got {}",
                                                                v
                                                            ));
                                                        };

                                                        let Ok(value) = reqwest::header::HeaderValue::from_str(value_as_string) else {
                                                            break 'res Err(anyhow!(
                                                                "baml.fetch_as: expected header value to be a string, got {}",
                                                                v
                                                            ));
                                                        };

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Remove illegal characters (spaces, colons) from header keys; use "Content-Type" not "Content-Type:"
  2. Validate each header name is a valid HTTP token before building the HttpRequest
  3. Trim whitespace from keys derived from config or user input

Example fix

// before (BAML)
let req = baml.HttpRequest{url: "https://api.example.com", method: "Get", headers: {"Content-Type: ": "application/json"}}
// after
let req = baml.HttpRequest{url: "https://api.example.com", method: "Get", headers: {"Content-Type": "application/json"}}
Defensive patterns

Strategy: validation

Validate before calling

const HEADER_NAME_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
function validateHeaderNames(headers) {
  for (const k of Object.keys(headers || {})) {
    if (!HEADER_NAME_RE.test(k)) throw new Error(`Invalid HTTP header name: "${k}"`);
  }
}

Type guard

function isValidHeaderName(k) { return /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/.test(k); }

Try / catch

try {
  const data = await runtime.callFunction(fnName, args);
} catch (e) {
  if (String(e).includes('expected header key to be a valid HTTP header name')) {
    // sanitize keys (trim, strip colons/spaces) and retry
  } else throw e;
}

Prevention

When it happens

Trigger: A header map whose key contains spaces, colons, non-ASCII characters, or is empty — e.g. headers{"Content Type": "json"} or headers{"": "x"}.

Common situations: Copy-pasted header lines including the colon ("Content-Type:"), translated header lists from curl commands, or dynamically built header names from user input.

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/b7819088717b7877. Report an issue: GitHub.