Opened 64 minutes ago
#37457 new Bug
forms.JSONField raises an unhandled ValueError for JSON integers exceeding Python's digit limit
| Reported by: | steinsgate | Owned by: | |
|---|---|---|---|
| Component: | Forms | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Submitting a JSON integer exceeding Python's configured integer string conversion limit to forms.JSONField causes an unhandled ValueError instead of a field validation error.
Tested on Python 3.14.4 with the default limit of 4300 digits, using Django main at 36920bb4766679f5b32445797dcc5d32b8ff5ad2 (6.2 alpha), on Windows. No custom encoder or decoder is required.
Minimal reproduction
import sys from django.conf import settings settings.configure(USE_I18N=False) from django import forms class PayloadForm(forms.Form): payload = forms.JSONField() limit = sys.get_int_max_str_digits() assert limit > 0 form = PayloadForm({"payload": "9" * (limit + 1)}) form.is_valid()
Actual result:
ValueError: Exceeds the limit (4300 digits) for integer string conversion: value has 4301 digits; use sys.set_int_max_str_digits() to increase the limit
Expected result: is_valid() returns False, with the usual JSONField validation error (code "invalid"). This report is about handling rejected input at the form boundary, not accepting arbitrary-length integers or disabling Python's conversion limit.
Related paths and controls
The same exception occurs with the integer inside a JSON array or object. It also escapes from forms.JSONField().clean(raw), the bound field value() method, and forms.JSONField().has_changed(None, raw). For bound input, the expected behavior is to preserve the submitted text for redisplay.
At the default limit, 4300-digit integers work; 4301-digit integers fail. Quoted digit strings and ordinary malformed JSON are handled normally. Adjusting the interpreter limit from 640 to 700 makes the same 641-digit input change from failure to success (the original limit was restored). IntegerField converts the equivalent conversion failure into ValidationError. A JSONDecoder using parse_int=str accepts the oversized numeric token, so any fix should preserve successful custom decoding.
Relation to #37418
#37418, fixed by 9014ca5 / PR https://github.com/django/django/pull/22132, handled RecursionError for deeply nested JSON. JSONField.to_python() and bound_data() now catch JSONDecodeError and RecursionError, but json.loads() raises a plain ValueError for this integer conversion limit, which still escapes both handlers.
A regression test should cover clean(), bound-value redisplay, and form validation; has_changed() is another affected caller of to_python(). Broadening the decoding exception handlers to handle ValueError appears worth considering, including the behavior of custom decoders.
The problem was reproduced through form/field APIs without a database. Other Django release branches and an HTTP/admin integration were not tested. No patch is attached.
AI assistance disclosure: OpenAI Codex assisted with investigation, reproduction scripts, and preparation of this report.