id summary reporter owner description type status component version severity resolution keywords cc stage has_patch needs_docs needs_tests needs_better_patch easy ui_ux 33351 path()/re_path() should raise a TypeError when kwargs is not a dict. Keryn Knight Pedro Schlickmann Mendes "Apparently, however many years into using Django, I'm still capable of making a ""newbie"" mistake and getting confused. So perhaps other actual new users encounter similar, especially given the lack of typing specifiers. I defined a URL like so: {{{ urlpatterns = [ path(""path/to/thing"", MyView.as_view(), ""my_view""), ] }}} which ... well, you either spot the issue immediately or you don't, and end up with the following. If you try and `resolve()` the path (eg: by making a request in your browser), you'll get something like: {{{ In [3]: resolve(""/path/to/thing"") ~/Code/django/django/urls/base.py in resolve(path, urlconf) 22 if urlconf is None: 23 urlconf = get_urlconf() ---> 24 return get_resolver(urlconf).resolve(path) 25 26 ~/Code/django/django/urls/resolvers.py in resolve(self, path) 586 for pattern in self.url_patterns: 587 try: --> 588 sub_match = pattern.resolve(new_path) 589 except Resolver404 as e: 590 self._extend_tried(tried, pattern, e.args[0].get('tried')) ~/Code/django/django/urls/resolvers.py in resolve(self, path) 388 new_path, args, kwargs = match 389 # Pass any extra_kwargs as **kwargs. --> 390 kwargs.update(self.default_args) 391 return ResolverMatch(self.callback, args, kwargs, self.pattern.name, route=str(self.pattern)) 392 ValueError: dictionary update sequence element #0 has length 1; 2 is required }}} The crux of the issue being that I ''meant'' to give the URL a name, and it's a super unfortunate history that `kwargs` comes ''before'' the `name` argument (because nearly everyone gives a URL a name, but passing static kwargs is ''comparatively'' infrequent). So what's actually happened is that `kwargs = ""my_view""` and eventually `self.default_args = ""my_view""`. If I update to `path(""path/to/thing"", MyView.as_view(), ""my_view"", name=""my_view"")`, leaving the type incorrect, I can get the following error via reverse, too: {{{ In [4]: reverse(""my_view"") ~/Code/django/django/urls/base.py in reverse(viewname, urlconf, args, kwargs, current_app) 84 resolver = get_ns_resolver(ns_pattern, resolver, tuple(ns_converters.items())) 85 ---> 86 return resolver._reverse_with_prefix(view, prefix, *args, **kwargs) 87 88 ~/Code/django/django/urls/resolvers.py in _reverse_with_prefix(self, lookup_view, _prefix, *args, **kwargs) 669 if set(kwargs).symmetric_difference(params).difference(defaults): 670 continue --> 671 if any(kwargs.get(k, v) != v for k, v in defaults.items()): 672 continue 673 candidate_subs = kwargs AttributeError: 'str' object has no attribute 'items' }}} Both of these suggest that either there should be a type-guard in `_path` to assert it's ''dict-ish'' (if not `None`), or a system check on `URLPattern` to raise a friendly message. Well, they actually continue to suggest to me that everything after the `view` argument should be keyword-only, or that kwargs should come later, but I suspect those to be a harder sell ;) This is specifically around the `kwargs`, but it doesn't look like there's any guarding on the `name` either, and I feel like a name of `{'test': 'test'}` (i.e. accidentally swapped both positionals) is likely to bite & cause an issue somewhere." Cleanup/optimization closed Core (URLs) dev Normal fixed path _path URLPattern check Egor R Pedro Schlickmann Mendes Ready for checkin 1 0 0 0 1 0