{"record":{"id":"406020802d8da717","repo":"hasura/graphql-engine","slug":"unexpected-status-code-0-406020","errorCode":null,"errorMessage":"Unexpected status code: {0}","messagePattern":"Unexpected status code: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/crates/plugins/pre-response-plugin/src/execute/common.rs","lineNumber":27,"sourceCode":"use lang_graphql::{ast::common as ast, http::RawRequest};\nuse open_dds::plugins::{LifecyclePluginUrl, LifecyclePreResponsePluginHookConfigRequest};\nuse reqwest::header::HeaderValue;\nuse serde::Serialize;\nuse tracing_util::{ErrorVisibility, TraceableError};\n\n#[derive(Debug, thiserror::Error)]\npub enum Error {\n    #[error(\"Error while making the HTTP request to the pre-parse plugin {0} - {1}\")]\n    ErrorWhileMakingHTTPRequestToTheHook(String, reqwest::Error),\n    #[error(\"Error while building the request for the pre-parse plugin {0} - {1}\")]\n    BuildRequestError(String, String),\n    #[error(\"Reqwest error: {0}\")]\n    ReqwestError(reqwest::Error),\n    #[error(\"Error parsing the request: {0}\")]\n    PluginRequestParseError(serde_json::Error),\n    #[error(\"Error parsing the engine response: {0}\")]\n    EngineResponseParseError(serde_json::Error),\n    #[error(\"Unexpected status code: {0}\")]\n    UnexpectedStatusCode(u16),\n    #[error(\"Error serializing the modified response: {0}\")]\n    ResponseSerializationError(serde_json::Error),\n    #[error(\"Error while preparing the response: {0}\")]\n    ResponsePreparationError(axum::http::Error),\n}\n\nimpl TraceableError for Error {\n    fn visibility(&self) -> ErrorVisibility {\n        ErrorVisibility::Internal\n    }\n}\n\nimpl Error {\n    pub fn to_graphql_response(self) -> lang_graphql::http::Response {\n        let is_internal = match &self {\n            Error::ErrorWhileMakingHTTPRequestToTheHook(_, _)\n            | Error::UnexpectedStatusCode(_)","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/plugins/pre-response-plugin/src/execute/common.rs#L9-L45","documentation":"The pre-response hook returned an HTTP status code the executor does not treat as success (or as its continue signal). The numeric code is included in the message.","triggerScenarios":"The pre-response hook replies 4xx/5xx — e.g. it rejects the modified-response payload, hits an internal error (500), or requires auth the engine doesn't provide.","commonSituations":"Hook endpoint path changed between versions returning 404; auth token mismatch returning 401; plugin bug returning 500 on edge-case responses.","solutions":["Check the hook service logs for the failing request.","Confirm the endpoint path and method the engine calls match what the plugin exposes.","Align auth configuration between engine and hook.","Upgrade both sides together so the status contract matches."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"if let Error::UnexpectedStatusCode(code) = e {\n    // 401/403: fix auth; 404: fix path; 5xx: check hook logs; consider fail-open\n}","preventionTips":["Contract-test hook statuses including continue-signals.","Keep hook route paths stable across versions; version them explicitly.","Centralize engine↔hook auth config."],"tags":["http","status-code","plugin","rust","pre-response-hook"],"backgroundTag":"unexpected-http-status","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}