{"record":{"id":"6cafe91e57f2e3be","repo":"dbt-labs/dbt-core","slug":"http-status-as-error-is-not-enabled","errorCode":null,"errorMessage":"`http_status_as_error` is not enabled.","messagePattern":"`http_status_as_error` is not enabled\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/vortex-client/src/client.rs","lineNumber":244,"sourceCode":"        let mut message_batch = VortexMessageBatch {\n            request_id: uuid::Uuid::new_v4().to_string(),\n            payload: Vec::new(),\n        };\n        // Consume these messages into a batch's payload and then swap them back to\n        // the original messages vector to enable retries from the caller if needed.\n        std::mem::swap(&mut self.messages, &mut message_batch.payload);\n        let body = message_batch.encode_to_vec();\n        std::mem::swap(&mut self.messages, &mut message_batch.payload);\n        body\n    }\n\n    fn on_error(&mut self, error: ureq::Error) {\n        #[allow(clippy::single_match)]\n        match error {\n            ureq::Error::StatusCode(_) => {\n                // Status codes should be handled in `on_response`\n                // because `http_status_as_error` is not enabled.\n                unreachable!(\"`http_status_as_error` is not enabled.\")\n            }\n            _ => (),\n        }\n        self.last_error = Some(error);\n        self.backoff();\n    }\n\n    fn on_response(&mut self, status: http::StatusCode, text: String) {\n        if status.is_success() {\n            self.clear_after_success();\n            trace!(\"Successfully sent telemetry batch.\");\n        } else {\n            self.backoff();\n            trace!(\"Failed to send batch of messages: {status}: {text}\");\n            self.last_error = Some(ureq::Error::StatusCode(status.as_u16()));\n        }\n    }\n}","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/dbt-labs/dbt-core/blob/0267ce9170576975b76b64ce856b2e5848e96617/crates/vortex-client/src/client.rs#L226-L262","documentation":"vortex-client's HTTP retry hook asserts that status-code errors never reach on_error. The client is built with http_status_as_error disabled, so ureq delivers non-2xx statuses via on_response instead; a StatusCode error arriving here means the client was misconfigured. It is an internal invariant panic, not a network failure report.","triggerScenarios":"Calling request paths with a client configured with http_status_as_error = true (or a ureq agent constructed without the expected setting), so ureq::Error::StatusCode flows into on_error.","commonSituations":"Enabling http_status_as_error in client configuration; swapping the underlying ureq agent for a custom one with different error policies; upgrading ureq and changing error semantics.","solutions":["Do not enable http_status_as_error on the vortex client's ureq agent","Handle HTTP status codes in on_response, which is the designed path","If using a custom agent, keep its error behavior matching the client's assumptions","Report a bug if the panic occurs with default client settings"],"exampleFix":"// before\nAgentBuilder::new().http_status_as_error(true)...\n// after\nAgentBuilder::new().http_status_as_error(false)... // handle statuses in on_response","handlingStrategy":"validation","validationCode":"// before building the client, confirm the setting\nlet agent = ureq::AgentBuilder::new()\n    .http_status_as_error(false)\n    .build();","typeGuard":null,"tryCatchPattern":"// statuses are expected in on_response, not on_error:\nfn on_response(&mut self, resp: http::Response<&[u8]>) -> Result<(), ureq::Error> {\n    if !resp.status().is_success() {\n        self.last_error = Some(ureq::Error::StatusCode(resp.status().as_u16()));\n        self.backoff();\n    }\n    Ok(())\n}","preventionTips":["Leave http_status_as_error at its default (disabled)","Handle non-2xx statuses in on_response","Avoid replacing the ureq agent with custom error semantics","Add a config assertion that the client was built with the expected setting"],"tags":["http","client","panic","configuration"],"backgroundTag":"invalid-config-value","analyzedSha":"0267ce9170576975b76b64ce856b2e5848e96617","analyzedAt":"2026-09-07T21:53:39.732Z","contentChangedAt":"2026-09-07T21:53:39.732Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}