hasura/graphql-engine · error · Error

Error parsing the request: {0}

Error message

Error parsing the request: {0}

What it means

The pre-NDC-response plugin returned a 200 response, but its JSON body could not be parsed back into the expected (possibly mutated) response object; {0} is the serde_json error. This indicates the plugin's response does not match the wire schema the engine expects — usually a plugin/engine version mismatch or plugin bug.

Source

Thrown at v3/crates/plugins/pre-ndc-response-plugin/src/execute.rs:24

use reqwest::{
    Client,
    header::{InvalidHeaderName, InvalidHeaderValue},
};
use serde::{Deserialize, Serialize};
use std::{collections::BTreeMap, str::FromStr, sync::Arc};
use tracing_util::{ErrorVisibility, SpanVisibility, TraceableError, set_attribute_on_active_span};

#[derive(Debug, thiserror::Error)]
pub enum Error {
    #[error("Error while making the HTTP request to the pre-response plugin {0} - {1}")]
    ErrorWhileMakingHTTPRequestToTheHook(String, reqwest::Error),
    #[error("Error while building the request for the pre-response plugin {0} - {1}")]
    BuildRequestError(String, #[source] BuildRequestError),
    #[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),
    #[error("Internal error from plugin {plugin_name}")]
    PluginInternalError {
        plugin_name: String,
        error: serde_json::Value,
    },
    #[error("User error from plugin {plugin_name}")]
    PluginUserError {
        plugin_name: String,
        error: serde_json::Value,
    },
}

#[derive(Debug, thiserror::Error)]
pub enum BuildRequestError {
    #[error("Invalid header name {header_name}: {error}")]
    InvalidHeaderName {
        header_name: String,

View on GitHub (pinned to 724551b9ae)

Solutions

  1. Log the raw body to see whether it is JSON at all (HTML from a proxy is common)
  2. Match plugin and engine versions and redeploy together
  3. Ensure the plugin returns the exact response struct schema, unwrapped
  4. Remove any gateway/rewrite rules that mangle the plugin's response body
Defensive patterns

Strategy: validation

Validate before calling

let raw = resp.text().await?;
if !raw.trim_start().starts_with('{') { /* HTML/error page, don't parse */ }

Try / catch

match serde_json::from_str::<HookResponse>(&raw) {
    Ok(v) => v,
    Err(e) => { tracing::error!(raw, "unparseable hook response"); return Err(e.into()); }
}

Prevention

When it happens

Trigger: The hook returns successfully but resp.json() fails on the body — wrong shape, missing required fields, or invalid JSON entirely (e.g. an HTML error page from a proxy).

Common situations: Engine upgraded without upgrading the response plugin; a proxy in front returning HTML; plugin returning a wrapped object instead of the response itself.

Related errors


AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28). Data as JSON: /api/errors/0a7b9ecec7bd53e9. Report an issue: GitHub.