{"record":{"id":"02a2e02c43f341fd","repo":"hasura/graphql-engine","slug":"error-parsing-the-engine-response-0","errorCode":null,"errorMessage":"Error parsing the engine response: {0}","messagePattern":"Error parsing the engine response: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"v3/crates/plugins/pre-response-plugin/src/execute/common.rs","lineNumber":25,"sourceCode":"\nuse hasura_authn_core::Session;\nuse 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 {","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/v3/crates/plugins/pre-response-plugin/src/execute/common.rs#L7-L43","documentation":"The pre-response plugin received the engine's response body but could not deserialize it into the expected engine-response structure before passing it to the hook. This is a schema mismatch on the engine→plugin response contract.","triggerScenarios":"A change in the engine's serialized response shape (new/renamed fields) while the pre-response plugin crate is older, causing serde to fail while parsing the engine response.","commonSituations":"Upgrading the engine but not the plugins; response format changes between minor versions; non-UTF8 or truncated body upstream.","solutions":["Upgrade the pre-response plugin crate to the version matching the engine release.","Log the raw engine response body to identify the schema divergence.","If you own the schema, make plugin parsing tolerant (Option fields, aliases)."],"exampleFix":"// before\n#[derive(Deserialize)]\nstruct EngineResponse { data: Data }\n\n// after (tolerate new engine shapes)\n#[derive(Deserialize)]\nstruct EngineResponse { data: Data, #[serde(default)] meta: Option<serde_json::Value> }","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"match parse_engine_response(&bytes) {\n    Ok(r) => r,\n    Err(e) => { tracing::warn!(\"engine response schema mismatch: {e}\"); return original_response; } // pass through unmodified\n}","preventionTips":["Upgrade engine and pre-response plugin in lockstep.","Make plugin-side deserialization tolerant (Option/default) for non-critical fields.","Log raw engine responses on parse failure."],"tags":["json","serde","plugin","rust","pre-response-hook"],"backgroundTag":"json-deserialization-failed","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}