{"record":{"id":"793d6049ef4e6b06","repo":"headroomlabs-ai/headroom","slug":"invalid-upstream-url-0","errorCode":null,"errorMessage":"invalid upstream URL: {0}","messagePattern":"invalid upstream URL: (.+?)","errorType":"http","errorClass":"ProxyError::InvalidUpstream","httpStatus":502,"severity":"error","filePath":"crates/headroom-proxy/src/error.rs","lineNumber":12,"sourceCode":"//! Error types for the proxy.\n\nuse axum::http::StatusCode;\nuse axum::response::{IntoResponse, Response};\nuse thiserror::Error;\n\n#[derive(Debug, Error)]\npub enum ProxyError {\n    #[error(\"upstream request failed: {0}\")]\n    Upstream(#[from] reqwest::Error),\n\n    #[error(\"invalid upstream URL: {0}\")]\n    InvalidUpstream(String),\n\n    #[error(\"invalid header: {0}\")]\n    InvalidHeader(String),\n\n    #[error(\"websocket error: {0}\")]\n    WebSocket(String),\n\n    #[error(\"io error: {0}\")]\n    Io(#[from] std::io::Error),\n\n    /// PR-A8 / P5-59: request body exceeded the configured cap. RFC 7231\n    /// §6.5.11: 413 Payload Too Large. Previously surfaced as\n    /// `InvalidHeader` (400) which mis-classified an oversize body as a\n    /// header parse error; clients with retry-on-413 logic broke.\n    #[error(\"request body exceeds configured limit: {0}\")]\n    PayloadTooLarge(String),\n","sourceCodeStart":1,"sourceCodeEnd":30,"githubUrl":"https://github.com/headroomlabs-ai/headroom/blob/322425c43bffde1ed0b64fecf3cf5951565dd82b/crates/headroom-proxy/src/error.rs#L1-L30","documentation":"The configured upstream base URL could not be turned into a valid request target. Unlike ProxyError::Upstream (transport-time), this fails while building the outbound request from configuration, and maps to 502 Bad Gateway since the fault is on the proxy's chosen upstream, not the client's request.","triggerScenarios":"Config value like 'bedrock-runtime.us-east-1.amazonaws.com' (no scheme), 'http://[bad', or an upstream override whose path/query portion is invalid; URL parsed at request-build time and rejected.","commonSituations":"Typo'd or scheme-less --upstream/--base-url flag; environment variable with trailing whitespace or a newline; swapping an OpenAI-style URL into a Bedrock-style config (or vice versa) with incompatible path expectations.","solutions":["Fix the configured URL to include a full valid scheme+host, e.g. https://api.example.com — the {0} payload names what was invalid.","Add startup validation that parses the upstream URL once in main so misconfiguration is fatal at boot, not per-request 502s.","Echo the effective config at startup (log the resolved upstream URL) to catch env-var sourcing mistakes."],"exampleFix":"# before\nexport UPSTREAM_URL=bedrock-runtime.us-east-1.amazonaws.com\n\n# after\nexport UPSTREAM_URL=https://bedrock-runtime.us-east-1.amazonaws.com","handlingStrategy":"validation","validationCode":"// Startup: fail fast on unparseable upstream URL\nlet base = url::Url::parse(&cfg.upstream)\n    .map_err(|e| format!(\"invalid upstream URL {cfg_upstream:?}: {e}\"))?;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always include scheme (https://) in configured upstream URLs.","Log the resolved effective config at boot to catch env-var mistakes.","Validate in main so misconfig aborts startup instead of 502ing per request."],"tags":["config","url","upstream","http","rust"],"backgroundTag":null,"analyzedSha":"322425c43bffde1ed0b64fecf3cf5951565dd82b","analyzedAt":"2026-08-15T01:03:05.481Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}