[Django] #36695: Model field validator with a generic parameter causes infinite recursion when making migrations

14 views
Skip to first unread message

Django

unread,
Oct 29, 2025, 8:47:18 AM10/29/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------+--------------------------------------
Reporter: Michal Dabski | Type: Bug
Status: new | Component: Migrations
Version: 4.2 | Severity: Normal
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Minimal code to reproduce (in `models.py`) in `Django==4.2.25`

{{{
from django.utils.deconstruct import deconstructible
from django.db import models

@deconstructible
class SchemaValidator:
def __init__(self, expected_type: type):
pass

def __call__(self, *args, **kwargs):
pass

class TestModel(models.Model):
config: dict[str, float] =
models.JSONField(validators=[SchemaValidator(dict[str, float])])

}}}

This triggers an error when running makemigrations:

{{{
$ ./manage.py makemigrations
C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django_downloadview\__init__.py:4: UserWarning: pkg_resources is
deprecated as an API. See
https://setuptools.pypa.io/en/latest/pkg_resources.html. The pkg_resources
package is slated for removal as early as 2025-11-30. Refrain from using
this package or pin to Setuptools<81.
import pkg_resources
Migrations for 'audit_builder':
meg_forms\audit_builder\migrations\0083_alter_testmodel_config.py
- Alter field config on testmodel
Traceback (most recent call last):
File "C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django\db\migrations\serializer.py", line 214, in serialize
item_string, item_imports = serializer_factory(item).serialize()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django\db\migrations\serializer.py", line 214, in serialize
item_string, item_imports = serializer_factory(item).serialize()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django\db\migrations\serializer.py", line 214, in serialize
item_string, item_imports = serializer_factory(item).serialize()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Previous line repeated 996 more times]
File "C:\Users\Michal\src\mat-cms\.venv\Lib\site-
packages\django\db\migrations\serializer.py", line 389, in
serializer_factory
if isinstance(value, type_):
^^^^^^^^^^^^^^^^^^^^^^^^
RecursionError: maximum recursion depth exceeded
}}}

Debugging locally shows that:
* removing generic parameters from the `dict` type passed to
`SchemaValidator` does not trigger the error
* The loop happens in
`django.db.migrations.serializer.IterableSerializer.serialize`, it keeps
recursively invoking `serializer_factory(item).serialize()` with
`item='*dict[str, float]'` (`GenericAlias`)
--
Ticket URL: <https://code.djangoproject.com/ticket/36695>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

Django

unread,
Oct 29, 2025, 8:50:42 AM10/29/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------+--------------------------------------
Reporter: Michal Dabski | Owner: (none)
Type: Bug | Status: new
Component: Migrations | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Description changed by Michal Dabski:

Old description:
New description:

Minimal code to reproduce (in `models.py`) in `Django==4.2.25`

{{{
from django.utils.deconstruct import deconstructible
from django.db import models

@deconstructible
class SchemaValidator:
def __init__(self, expected_type: type):
pass

def __call__(self, *args, **kwargs):
pass

class TestModel(models.Model):
config: dict[str, float] =
models.JSONField(validators=[SchemaValidator(dict[str, float])])

}}}

This triggers an error when running makemigrations:

{{{
$ ./manage.py makemigrations
--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:1>

Django

unread,
Oct 29, 2025, 8:53:49 AM10/29/25
to django-...@googlegroups.com
* the same behaviour is with similar generic types - `list[str]`
* without the migration being created/applied, validation works as
expected

--
--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:2>

Django

unread,
Oct 29, 2025, 3:40:31 PM10/29/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------+--------------------------------------
Reporter: Michal Dabski | Owner: (none)
Type: Bug | Status: new
Component: Migrations | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------+--------------------------------------
Comment (by Augusto Pontes):

Hi michael, i will try to reproduce it, and see if i can give to you a
suggestion of how to solve it, i will test if this is still happening on
newer versions, in this case i will use the 5.2
--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:3>

Django

unread,
Oct 29, 2025, 4:26:54 PM10/29/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------+------------------------------------------
Reporter: Michal Dabski | Owner: Augusto Pontes
Type: Bug | Status: assigned
Component: Migrations | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Unreviewed
Has patch: 0 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------------
Changes (by Augusto Pontes):

* needs_better_patch: 0 => 1
* needs_docs: 0 => 1
* needs_tests: 0 => 1
* owner: (none) => Augusto Pontes
* status: new => assigned

--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:4>

Django

unread,
Oct 29, 2025, 4:50:18 PM10/29/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------+------------------------------------------
Reporter: Michal Dabski | Owner: Augusto Pontes
Type: Bug | Status: assigned
Component: Migrations | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------------
Changes (by Augusto Pontes):

* stage: Unreviewed => Accepted

--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:5>

Django

unread,
Oct 31, 2025, 1:14:13 AM10/31/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------+------------------------------------------
Reporter: Michal Dabski | Owner: Augusto Pontes
Type: Bug | Status: assigned
Component: Migrations | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 1
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------------
Comment (by Augusto Pontes):

https://github.com/django/django/pull/20025
--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:6>

Django

unread,
Oct 31, 2025, 10:42:18 AM10/31/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------+------------------------------------------
Reporter: Michal Dabski | Owner: Augusto Pontes
Type: Bug | Status: assigned
Component: Migrations | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 0 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
-------------------------------+------------------------------------------
Changes (by Jacob Walls):

* needs_docs: 1 => 0

--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:7>

Django

unread,
Nov 3, 2025, 2:59:04 PM11/3/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------------+-------------------------------------
Reporter: Michal Dabski | Owner: Augusto
| Pontes
Type: Bug | Status: assigned
Component: Migrations | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* needs_better_patch: 1 => 0
* needs_tests: 1 => 0
* stage: Accepted => Ready for checkin

Comment:

[https://github.com/django/django/pull/20048 PR with final edits]
--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:8>

Django

unread,
Nov 3, 2025, 8:43:56 PM11/3/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------------+-------------------------------------
Reporter: Michal Dabski | Owner: Augusto
| Pontes
Type: Bug | Status: assigned
Component: Migrations | Version: 4.2
Severity: Normal | Resolution:
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

* has_patch: 0 => 1

--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:9>

Django

unread,
Nov 3, 2025, 8:46:01 PM11/3/25
to django-...@googlegroups.com
#36695: Model field validator with a generic parameter causes infinite recursion
when making migrations
-------------------------------------+-------------------------------------
Reporter: Michal Dabski | Owner: Augusto
| Pontes
Type: Bug | Status: closed
Component: Migrations | Version: 4.2
Severity: Normal | Resolution: fixed
Keywords: | Triage Stage: Ready for
| checkin
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls <jacobtylerwalls@…>):

* resolution: => fixed
* status: assigned => closed

Comment:

In [changeset:"8af79e2c0c5608196369600268756772a6343525" 8af79e2]:
{{{#!CommitTicketReference repository=""
revision="8af79e2c0c5608196369600268756772a6343525"
Fixed #36695 -- Fixed handling of parameterized generics in migration
serialization.

Co-authored-by: Jacob Walls <jacobty...@gmail.com>
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/36695#comment:10>
Reply all
Reply to author
Forward
0 new messages