diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
index dbadfc6c90..dbe0c1d5f6 100644
--- a/django/db/models/fields/__init__.py
+++ b/django/db/models/fields/__init__.py
@@ -260,7 +260,7 @@ class Field(RegisterLookupMixin):
         for choices_group in self.choices:
             try:
                 group_name, group_choices = choices_group
-            except ValueError:
+            except (TypeError, ValueError):
                 # Containing non-pairs
                 break
             try:
diff --git a/tests/invalid_models_tests/test_ordinary_fields.py b/tests/invalid_models_tests/test_ordinary_fields.py
index 546c16a976..184041c24d 100644
--- a/tests/invalid_models_tests/test_ordinary_fields.py
+++ b/tests/invalid_models_tests/test_ordinary_fields.py
@@ -174,14 +174,20 @@ class CharFieldTests(TestCase):
         class Model(models.Model):
             field = models.CharField(max_length=10, choices=[(1, 2, 3), (1, 2, 3)])
 
-        field = Model._meta.get_field('field')
-        self.assertEqual(field.check(), [
-            Error(
-                "'choices' must be an iterable containing (actual value, human readable name) tuples.",
-                obj=field,
-                id='fields.E005',
-            ),
-        ])
+        class Model2(models.Model):
+            field = models.IntegerField(choices=[0])
+
+        for model in (Model, Model2):
+            with self.subTest(model.__name__):
+                field = model._meta.get_field('field')
+                self.assertEqual(field.check(), [
+                    Error(
+                        "'choices' must be an iterable containing (actual "
+                        "value, human readable name) tuples.",
+                        obj=field,
+                        id='fields.E005',
+                    ),
+                ])
 
     def test_choices_containing_lazy(self):
         class Model(models.Model):