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
- Remove illegal characters (spaces, colons) from header keys; use "Content-Type" not "Content-Type:"
- Validate each header name is a valid HTTP token before building the HttpRequest
- 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
- Strip trailing colons and whitespace from header keys parsed from curl/config
- Validate header names against RFC 7230 token characters before the call
- Never build header names from raw user input without sanitizing
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
- baml.fetch_as: expected header value to be a string, got {}
- baml.errors.InvalidArgument
- assertion failed
- baml.fetch_as: HTTP request failed: HTTP {} Body: {} at {:?}
- Missing required parameter: {param_name}
AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12).
Data as JSON: /api/errors/b7819088717b7877.
Report an issue: GitHub.