Skip to content

fix(routing): raise on paths that only differ in their path parameters - #4989

Open
NoiceHax wants to merge 1 commit into
litestar-org:mainfrom
NoiceHax:fix/issue-3622
Open

fix(routing): raise on paths that only differ in their path parameters#4989
NoiceHax wants to merge 1 commit into
litestar-org:mainfrom
NoiceHax:fix/issue-3622

Conversation

@NoiceHax

@NoiceHax NoiceHax commented Aug 14, 2026

Copy link
Copy Markdown

The routing trie collapses every path parameter at a given position into one node, so /{id:int} and /{id:str} resolve to the same node. Whichever route got registered last silently overwrote the earlier handler and made it unreachable. The issue discussion settled on raising an error instead of routing by parameter type, so registering paths like that now raises ImproperlyConfiguredException.

The check runs per method, so two paths that share a node but register different methods still work. OPTIONS is skipped. Litestar generates an OPTIONS handler for every path that does not declare one, so those handlers collide on a shared node even though no user handler is being shadowed. Re-registering the exact same route is still fine, which matters when the trie gets rebuilt after handlers are added to an app that already exists.

Tests are in tests/unit/test_asgi/test_routing_trie/test_mapping.py. I also added a note to the path parameter docs.

Closes #3622


📚 Documentation preview 📚: https://litestar-org.github.io/litestar-docs-preview/4989

The routing trie collapses every path parameter at a given position into a
single node, so paths such as '/{id:int}' and '/{id:str}' resolve to the very
same node and the route registered last silently replaced the handlers
registered before it, making them unreachable. Registering such paths now
raises an ImproperlyConfiguredException instead.

Closes litestar-org#3622
@NoiceHax
NoiceHax requested review from a team as code owners August 14, 2026 05:08
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 76.92308% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 67.42%. Comparing base (7e56d30) to head (9372d44).
⚠️ Report is 16 commits behind head on main.

Files with missing lines Patch % Lines
litestar/_asgi/routing_trie/mapping.py 76.92% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #4989      +/-   ##
==========================================
+ Coverage   67.41%   67.42%   +0.01%     
==========================================
  Files         293      293              
  Lines       15308    15320      +12     
  Branches     1736     1739       +3     
==========================================
+ Hits        10320    10330      +10     
- Misses       4839     4841       +2     
  Partials      149      149              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@provinzkraut

provinzkraut commented Aug 15, 2026

Copy link
Copy Markdown
Member

Thinking about this again, this does introduce some inconsistencies: You normally do not get an exception when you override a path, but in this special case you'll now get one. IMO we should either always raise / warn there or never.

If we were to do this, my vote would be to emit a warning for every handler which overrides another, unless the handler explicitly states that it intends to override another handler (e.g. by setting overrides="other_handler_name" to the handler decorator).

@litestar-org/members thoughts on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: Routing based on path parameter data type is not using first matching route handler

2 participants