From 3e85858d4191f96a952d433d30e5c2ae10c1005f Mon Sep 17 00:00:00 2001 From: Piotr Oleszczyk Date: Sat, 28 Feb 2026 21:46:47 +0100 Subject: [PATCH] fix(backend): sanitize NaN/Infinity/undefined in Gemini JSON response Models sometimes emit JS-style literals for unknown numeric fields. Replace NaN, Infinity, undefined with null before parsing. Also add error logging to capture raw response on parse failure. Co-Authored-By: Claude Sonnet 4.6 --- backend/innercontext/api/products.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/innercontext/api/products.py b/backend/innercontext/api/products.py index d65b5db..9630ae2 100644 --- a/backend/innercontext/api/products.py +++ b/backend/innercontext/api/products.py @@ -1,8 +1,12 @@ import json +import logging +import re from datetime import date from typing import Optional from uuid import UUID, uuid4 +log = logging.getLogger(__name__) + from fastapi import APIRouter, Depends, HTTPException, Query from google.genai import types as genai_types from pydantic import ValidationError @@ -369,9 +373,14 @@ def parse_product_text(data: ProductParseRequest) -> ProductParseResponse: end = raw.rfind("}") if start != -1 and end != -1: raw = raw[start : end + 1] + # Replace JS-style non-JSON literals that some models emit + raw = re.sub(r":\s*NaN\b", ": null", raw) + raw = re.sub(r":\s*Infinity\b", ": null", raw) + raw = re.sub(r":\s*undefined\b", ": null", raw) try: parsed = json.loads(raw) - except (json.JSONDecodeError, Exception) as e: + except json.JSONDecodeError as e: + log.error("Gemini parse-text raw response (failed):\n%s", raw) raise HTTPException(status_code=502, detail=f"LLM returned invalid JSON: {e}") try: return ProductParseResponse.model_validate(parsed)