hasura/graphql-engine · error · Error
Error serializing the modified response: {0}
Error message
Error serializing the modified response: {0} What it means
After the hook mutates the response, the pre-response plugin failed to serialize the modified response back to JSON (serde_json::Error). This happens on the write side, when producing the body to return.
Source
Thrown at v3/crates/plugins/pre-response-plugin/src/execute/common.rs:29
use reqwest::header::HeaderValue;
use serde::Serialize;
use tracing_util::{ErrorVisibility, TraceableError};
#[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("Error parsing the request: {0}")]
PluginRequestParseError(serde_json::Error),
#[error("Error parsing the engine response: {0}")]
EngineResponseParseError(serde_json::Error),
#[error("Unexpected status code: {0}")]
UnexpectedStatusCode(u16),
#[error("Error serializing the modified response: {0}")]
ResponseSerializationError(serde_json::Error),
#[error("Error while preparing the response: {0}")]
ResponsePreparationError(axum::http::Error),
}
impl TraceableError for Error {
fn visibility(&self) -> ErrorVisibility {
ErrorVisibility::Internal
}
}
impl Error {
pub fn to_graphql_response(self) -> lang_graphql::http::Response {
let is_internal = match &self {
Error::ErrorWhileMakingHTTPRequestToTheHook(_, _)
| Error::UnexpectedStatusCode(_)
| Error::ResponseSerializationError(_)
| Error::ResponsePreparationError(_) => false,View on GitHub (pinned to 724551b9ae)
Solutions
- Inspect the modified response produced by the hook for non-serializable values (NaN, Infinity, invalid map keys).
- Fix the hook to emit plain, JSON-safe values.
- Sanitize/normalize hook output before merging into the response.
Example fix
// before (hook emits NaN)
let v = serde_json::json!({ "score": f64::NAN });
// after
let v = serde_json::json!({ "score": null }); Defensive patterns
Strategy: validation
Validate before calling
// hook side: ensure JSON-safe values before returning
fn sanitize(v: f64) -> serde_json::Value {
if v.is_finite() { v.into() } else { serde_json::Value::Null }
} Try / catch
match serde_json::to_value(&modified) {
Ok(v) => v,
Err(e) => { tracing::warn!("hook produced unserializable response: {e}"); engine_response_untouched }
} Prevention
- Never emit NaN/Infinity from hooks; use null.
- Round-trip test hook output through serde_json in the hook's own tests.
- Validate mutated structures against the response model before returning.
When it happens
Trigger: The hook returns response content that cannot round-trip through the engine's response model — e.g. non-serializable values, or a structure that serde rejects on serialize (map with non-string keys, NaN in serde_json strict mode).
Common situations: Hook injecting unusual JSON values (NaN/Infinity floats) that serde_json refuses; deeply mutated structures violating the response type.
Related errors
- Error parsing the request: {0}
- Error parsing the engine response: {0}
- Serialization error: {0}
- Serialization error: {0}
- Error parsing the request: {0}
AI-assisted analysis of hasura/graphql-engine@724551b9ae (2026-08-28).
Data as JSON: /api/errors/d36c124b8762c67f.
Report an issue: GitHub.