django-upgrade 1.32.0 has shipped with 44 bug fixes, all found and fixed by Claude given the simple prompt 'Find and fix bugs.' Notable fixes include incorrect url() to path() conversions that mishandled literal angle brackets and unescaped dots, a five-year-old bug that swapped html.unescape() for html.escape(), and a TestCase.multi_db=False mapping that incorrectly blocked all database queries instead of just non-default ones. The author argues that since LLMs make finding such bugs cheap, the bar for software quality should rise, while noting fixes still need review and deterministic linting.

5m read timeFrom adamj.eu
Post cover image
Table of contents
Bad url() to path() conversionsEscaping backwardsTestCase.multi_db = False fixer blocking all database queriesBar height++Fin

Questions this post answers

What bug did django-upgrade have in its multi_db to databases conversion for Django TestCase?

Versions before 1.32.0 incorrectly rewrote the deprecated multi_db = False attribute to databases = [], which blocks queries against all databases. The correct rewrite is databases = ["default"], since Django's deprecated multi_db = False shim still allowed queries against the default database. This bug, introduced in django-upgrade 1.2.0, could break tests with DatabaseOperationForbidden errors and was fixed in PR #727. Track fixer bugs like this one on daily.dev before they silently break your Django test suite.

Why did django-upgrade's url() to path() fixer produce incorrect routes for URLs with literal angle brackets or unescaped dots?

The fixer copied regex angle brackets like <page> through unchanged, but in path() route syntax those characters declare parameters instead of matching literal text, so /go/<page>/ started matching /go/anything/ and passing an unexpected keyword argument, or raising ImproperlyConfigured if the bracketed text wasn't a valid identifier. Similarly, unescaped dots in regex (matching any character) were treated as literal dots in path(), silently narrowing which URLs matched. Fixed in django-upgrade PRs #715 and #710. Developers upgrading Django URL configs can follow fixer changes like this on daily.dev.

What prompt did Claude use to find 44 bugs in django-upgrade 1.32.0?

The prompt was simply 'Find and fix bugs.' Using this instruction across two rounds of self-directed bug discovery, Claude found and fixed 44 bugs in the django-upgrade tool, matching the project's coding style and changelog conventions, and needed one further prompt to split the fixes into individual commits for review. Anyone weighing AI agents for bug-hunting can compare real results like this via daily.dev.

1.3K Impressions