hasura/graphql-engine · error · Error
Error parsing the request: {0}
Error message
Error parsing the request: {0} What it means
Thrown when the JSON payload returned by (or sent to) the pre-parse hook fails to deserialize into the expected plugin request structure (serde_json::error::Error). This is a schema mismatch between what the engine serializes/expects and what the hook produces/expects.
Source
Thrown at v3/crates/plugins/pre-parse-plugin/src/execute.rs:33
};
/// HTTP status code used by pre-parse plugins to indicate they want to continue
/// processing with a modified request body.
///
/// We use 299 (an unassigned 2xx status code) as a special signal for this.
const CONTINUE_WITH_REQUEST_STATUS: u16 = 299;
#[derive(Debug, thiserror::Error)]
pub enum Error {
#[error("Error while making the HTTP request to the pre-parse plugin {0} - {1}")]
ErrorWhileMakingHTTPRequestToTheHook(String, reqwest::Error),
#[error("Error while building the request for the pre-parse plugin {0} - {1}")]
BuildRequestError(String, String),
#[error("Reqwest error: {0}")]
ReqwestError(reqwest::Error),
#[error("Unexpected status code: {0}")]
UnexpectedStatusCode(u16),
#[error("Error parsing the request: {0}")]
PluginRequestParseError(serde_json::error::Error),
}
impl Error {
pub fn is_internal(&self) -> bool {
match self {
Error::ErrorWhileMakingHTTPRequestToTheHook(_, _) | Error::UnexpectedStatusCode(_) => {
false
}
Error::BuildRequestError(_, _)
| Error::ReqwestError(_)
| Error::PluginRequestParseError(_) => true,
}
}
pub fn into_graphql_error(self) -> lang_graphql::http::GraphQLError {
lang_graphql::http::GraphQLError {
message: self.to_string(),View on GitHub (pinned to 724551b9ae)
Solutions
- Pin engine and plugin crates to compatible versions (schema contract).
- Log the raw hook response body to see exactly what failed to parse.
- If a proxy intercepts the hook, exclude the plugin route or fix the proxy's error responses.
- Add tolerant serde attributes (Option fields, #[serde(default)]) on the plugin schema if you control it.
Example fix
// before (strict, breaks when hook omits a field)
#[derive(Deserialize)]
struct HookRequest { op: String, target: String }
// after
#[derive(Deserialize)]
struct HookRequest { op: String, #[serde(default)] target: Option<String> } Defensive patterns
Strategy: validation
Validate before calling
// hook side: verify payload matches before responding
let parsed: PluginRequest = serde_json::from_str(&body)
.map_err(|e| (http::StatusCode::BAD_REQUEST, e.to_string())); Try / catch
match serde_json::from_str::<PluginRequest>(&raw) {
Ok(r) => r,
Err(e) => { tracing::warn!("schema mismatch: {e}"); fallback_default() }
} Prevention
- Share the request/response types via a common crate between engine and hook.
- Add golden-file JSON tests for the hook contract.
- Log raw bodies on parse failure to speed diagnosis.
When it happens
Trigger: The hook returns a JSON body whose fields don't match the expected request type (missing fields, wrong types, trailing data), or the engine fails to parse the hook's instruction payload.
Common situations: Engine and plugin built from different versions with a changed schema; plugin returning an error JSON instead of the expected payload; a proxy injecting an HTML error page that gets parsed as JSON.
Related errors
- Serialization error: {0}
- Serialization error: {0}
- Error parsing the request: {0}
- Error parsing the engine response: {0}
- Error serializing the modified response: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/f15efaa33f62c8dc.
Report an issue: GitHub.