Environment
- python-genai: 1.73.1 (bug still present in 2.7.0, see line refs below)
- Python: 3.14.3 (any Python ≥ 3.11 with the default
int_max_str_digits=4300 is affected)
- Model:
gemini-3-flash-preview
Description
When response_schema / response_json_schema is set, GenerateContentResponse._from_response eagerly parses the response text to populate .parsed:
# google/genai/types.py (v2.7.0, lines 8255, 8282; also 8238, 8271 for the pydantic branches)
try:
result_text = result._get_text()
if result_text is not None:
result.parsed = json.loads(result_text)
# may not be a valid json per stream response
except json.decoder.JSONDecodeError:
pass
json.loads can raise more than JSONDecodeError: since Python 3.11 (CVE-2020-10735 mitigation), parsing an integer literal longer than sys.get_int_max_str_digits() (default 4300) raises a plain ValueError:
ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 25410 digits; use sys.set_int_max_str_digits() to increase the limit
This is not a subclass of JSONDecodeError, so it escapes the guard and propagates out of generate_content() — after the API already returned HTTP 200. The caller cannot distinguish this from an SDK/transport failure, and there is no way to access the response (e.g. .text) because the exception is raised before the response object is returned.
Reproduction
We hit this in production: the model occasionally emits a degenerate/runaway integer literal in structured output (25,410 digits in our case). The application can't prevent that — it's model output. Minimal demonstration of the parsing gap:
import json
try:
json.loads('{"count": ' + "1" * 5000 + "}")
except json.JSONDecodeError:
print("handled") # <- never reached
except ValueError as e:
print(f"escapes: {e}") # <- this is what propagates out of generate_content()
Production stack trace (python-genai 1.73.1):
ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 25410 digits; use sys.set_int_max_str_digits() to increase the limit
at raw_decode (json/decoder.py:361)
at decode (json/decoder.py:345)
at loads (json/__init__.py:352)
at _from_response (google/genai/types.py:8172)
at _generate_content (google/genai/models.py:4753)
at generate_content (google/genai/models.py:6276)
Expected behavior
An unparseable response body (for whatever reason) should degrade the same way a malformed-JSON response does: .parsed stays None and the caller gets the response object back, with .text available for its own error handling.
Suggested fix
json.JSONDecodeError is a subclass of ValueError, so widening the four except json.decoder.JSONDecodeError: clauses in _from_response to except ValueError: keeps the existing behavior and also covers the int-limit case (lines 8238, 8255, 8271, 8282 in v2.7.0).
Environment
int_max_str_digits=4300is affected)gemini-3-flash-previewDescription
When
response_schema/response_json_schemais set,GenerateContentResponse._from_responseeagerly parses the response text to populate.parsed:json.loadscan raise more thanJSONDecodeError: since Python 3.11 (CVE-2020-10735 mitigation), parsing an integer literal longer thansys.get_int_max_str_digits()(default 4300) raises a plainValueError:This is not a subclass of
JSONDecodeError, so it escapes the guard and propagates out ofgenerate_content()— after the API already returned HTTP 200. The caller cannot distinguish this from an SDK/transport failure, and there is no way to access the response (e.g..text) because the exception is raised before the response object is returned.Reproduction
We hit this in production: the model occasionally emits a degenerate/runaway integer literal in structured output (25,410 digits in our case). The application can't prevent that — it's model output. Minimal demonstration of the parsing gap:
Production stack trace (python-genai 1.73.1):
Expected behavior
An unparseable response body (for whatever reason) should degrade the same way a malformed-JSON response does:
.parsedstaysNoneand the caller gets the response object back, with.textavailable for its own error handling.Suggested fix
json.JSONDecodeErroris a subclass ofValueError, so widening the fourexcept json.decoder.JSONDecodeError:clauses in_from_responsetoexcept ValueError:keeps the existing behavior and also covers the int-limit case (lines 8238, 8255, 8271, 8282 in v2.7.0).