{"record":{"id":"b7819088717b7877","repo":"BoundaryML/baml","slug":"baml-fetch-as-expected-header-key-to-be-a-valid-http-header","errorCode":null,"errorMessage":"baml.fetch_as: expected header key to be a valid HTTP header name, got {}","messagePattern":"baml\\.fetch_as: expected header key to be a valid HTTP header name, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"engine/baml-runtime/src/async_vm_runtime.rs","lineNumber":636,"sourceCode":"\n                                                let mut req = match method.as_str() {\n                                                    \"Get\" => client.get(url),\n                                                    \"Post\" => client.post(url),\n                                                    \"Put\" => client.put(url),\n                                                    \"Patch\" => client.patch(url),\n                                                    \"Delete\" => client.delete(url),\n                                                    _ => break 'res Err(anyhow!(\n                                                        \"baml.fetch_as: expected method to be a valid HTTP method, got {}\",\n                                                        method\n                                                    ))\n                                                };\n\n                                                if let Some(BamlValue::Map(headers)) = fields.get(\"headers\") {\n                                                    let mut header_map = reqwest::header::HeaderMap::new();\n\n                                                    for (k, v) in headers {\n                                                        let Ok(key) = reqwest::header::HeaderName::from_str(k) else {\n                                                            break 'res Err(anyhow!(\n                                                                \"baml.fetch_as: expected header key to be a valid HTTP header name, got {}\",\n                                                                k\n                                                            ));\n                                                        };\n\n                                                        let Some(value_as_string) = v.as_str() else {\n                                                            break 'res Err(anyhow!(\n                                                                \"baml.fetch_as: expected header value to be a string, got {}\",\n                                                                v\n                                                            ));\n                                                        };\n\n                                                        let Ok(value) = reqwest::header::HeaderValue::from_str(value_as_string) else {\n                                                            break 'res Err(anyhow!(\n                                                                \"baml.fetch_as: expected header value to be a string, got {}\",\n                                                                v\n                                                            ));\n                                                        };","sourceCodeStart":618,"sourceCodeEnd":654,"githubUrl":"https://github.com/BoundaryML/baml/blob/bd85ce9dee1463ff04d27efd20531013a4ff46c1/engine/baml-runtime/src/async_vm_runtime.rs#L618-L654","documentation":"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.","triggerScenarios":"A header map whose key contains spaces, colons, non-ASCII characters, or is empty — e.g. headers{\"Content Type\": \"json\"} or headers{\"\": \"x\"}.","commonSituations":"Copy-pasted header lines including the colon (\"Content-Type:\"), translated header lists from curl commands, or dynamically built header names from user input.","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"],"exampleFix":"// before (BAML)\nlet req = baml.HttpRequest{url: \"https://api.example.com\", method: \"Get\", headers: {\"Content-Type: \": \"application/json\"}}\n// after\nlet req = baml.HttpRequest{url: \"https://api.example.com\", method: \"Get\", headers: {\"Content-Type\": \"application/json\"}}","handlingStrategy":"validation","validationCode":"const HEADER_NAME_RE = /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/;\nfunction validateHeaderNames(headers) {\n  for (const k of Object.keys(headers || {})) {\n    if (!HEADER_NAME_RE.test(k)) throw new Error(`Invalid HTTP header name: \"${k}\"`);\n  }\n}","typeGuard":"function isValidHeaderName(k) { return /^[!#$%&'*+\\-.^_`|~0-9A-Za-z]+$/.test(k); }","tryCatchPattern":"try {\n  const data = await runtime.callFunction(fnName, args);\n} catch (e) {\n  if (String(e).includes('expected header key to be a valid HTTP header name')) {\n    // sanitize keys (trim, strip colons/spaces) and retry\n  } else throw e;\n}","preventionTips":["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"],"tags":["baml","http","headers","validation"],"backgroundTag":"invalid-argument-format","analyzedSha":"bd85ce9dee1463ff04d27efd20531013a4ff46c1","analyzedAt":"2026-09-12T03:38:25.718Z","contentChangedAt":"2026-09-12T03:38:25.718Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}