BoundaryML/baml · error · HttpError

JSON serialization error: {}

Error message

JSON serialization error: {}

What it means

A From<serde_json::Error> impl in the playground server's error module converts any serde_json failure into an HttpError with message 'JSON serialization error'. It fires whenever request/response bodies fail to serialize or deserialize as JSON in the playground API.

Source

Thrown at engine/playground-server/src/api/errors.rs:33

    fn into_response(self) -> axum::response::Response {
        // For IPC, keep it simple but preserve error chain information
        let error_message = format!("{:#}", self.0);

        (
            StatusCode::INTERNAL_SERVER_ERROR,
            Json(json!({
                "error": error_message,
                "type": "InternalError"
            })),
        )
            .into_response()
    }
}

// Keep existing From implementation for backward compatibility
impl From<serde_json::Error> for HttpError {
    fn from(err: serde_json::Error) -> Self {
        HttpError(anyhow::anyhow!("JSON serialization error: {}", err))
    }
}

#[derive(Debug)]
pub enum ApiError {
    NotFound(String),
    BadRequest(String),
    InternalError(String),
    Unauthorized(String),
}

impl IntoResponse for ApiError {
    fn into_response(self) -> axum::response::Response {
        let (status, message) = match self {
            ApiError::NotFound(msg) => (StatusCode::NOT_FOUND, msg),
            ApiError::BadRequest(msg) => (StatusCode::BAD_REQUEST, msg),
            ApiError::InternalError(msg) => (StatusCode::INTERNAL_SERVER_ERROR, msg),
            ApiError::Unauthorized(msg) => (StatusCode::UNAUTHORIZED, msg),

View on GitHub (pinned to bd85ce9dee)

Solutions

  1. Validate the request body is well-formed JSON matching the endpoint schema
  2. Check for NaN/Infinity or non-string map keys in values being serialized
  3. Inspect the inner serde_json error for the exact field/path that failed
  4. Fix the struct/serde attributes so all payload types are JSON-compatible

Example fix

// before: map with non-string key breaks serde_json
HashMap<i64, Diagnosis> -> HttpError(JSON serialization error)
// after
HashMap<String, Diagnosis> // or serde(with = "serialize_as_string_keys")
Defensive patterns

Strategy: validation

Validate before calling

try { JSON.parse(requestBody); } catch (e) { return 400; } // reject malformed JSON before hitting the API
// and sanitize payload values:
const safe = JSON.parse(JSON.stringify(payload, (_, v) => Number.isNaN(v) ? null : v));

Type guard

function isJsonObject(v: unknown): v is Record<string, unknown> { return typeof v === 'object' && v !== null && !Array.isArray(v); }

Try / catch

match result { Err(HttpError(e)) if e.to_string().contains("JSON serialization error") => respond(400, format!("invalid JSON: {e}")), Err(e) => respond(500, e.to_string()), Ok(v) => respond(200, v) }

Prevention

When it happens

Trigger: Serializing an API response whose types aren't JSON-representable (maps with non-string keys, NaN values), or deserializing a client request body that isn't valid JSON or doesn't match the expected schema.

Common situations: Client posting malformed JSON to playground endpoints; response payloads containing f64::NAN/Infinity; type changes in API structs breaking older clients; map keys that serde_json rejects.

Understand the failure class

Background: "JSON serialization failed", "not JSON serializable", "Failed to serialize": why JSON marshaling errors happen and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of BoundaryML/baml@bd85ce9dee (2026-09-12). Data as JSON: /api/errors/8d561c396dd3d4e5. Report an issue: GitHub.