Skip to content

Commit bb7c1c5

Browse files
committed
Add duplicate root route declarations pattern
Rails 4 raises ArgumentError: Invalid route name, already in use: 'root' when the routes file has more than one `root` declaration (typically one per constraint block). Rails 3.2 was lenient about duplicate names with different constraints, so this slips through on many 3.x codebases. The naive fix — give each duplicate an `as:` — silently breaks every root_path / root_url caller in the codebase because the :root name is no longer registered to any declaration. Real apps have dozens to hundreds of these helper calls in controllers, views, mailers, and tests. Correct fix: keep the FIRST declaration as the default :root, only add `as:` to the SECOND and subsequent. Includes a grep verification step so operators confirm no caller targets a constraint-bound root that was renamed. Classified high_priority / kind: breaking — Rails 4 boot raises outright on the duplicate.
1 parent de9009c commit bb7c1c5

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

rails-upgrade/detection-scripts/patterns/rails-40-patterns.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,16 @@ upgrade_findings:
172172
fix: "Add via: :get (or appropriate method) or replace with get/post/put/patch/delete helper"
173173
variable_name: "MATCH_WITHOUT_VIA"
174174

175+
- name: "Duplicate root route declarations across constraints"
176+
kind: "breaking"
177+
pattern: "^\\s*root\\s+(to:|=>)"
178+
exclude: ""
179+
search_paths:
180+
- "config/"
181+
explanation: "Rails 4 raises `ArgumentError: Invalid route name, already in use: 'root'` when the routes file has more than one `root` declaration (typically one per constraint block). Rails 3.2 was lenient about duplicate names with different constraints"
182+
fix: "Keep the FIRST `root` declaration as the default `:root` name; add `as: :<unique_name>` to the SECOND and subsequent declarations. Renaming all of them (giving the first an `as:` too) silently breaks every `root_path` / `root_url` call site because the `:root` name is no longer registered. Real apps have dozens to hundreds of these helper calls. Verification step: `grep -rnE \"\\b(root_path|root_url)\\b\" app/ config/ lib/` and confirm no caller targets a constraint-bound root that was renamed"
183+
variable_name: "DUPLICATE_ROOT_ROUTES"
184+
175185
medium_priority:
176186
- name: "rescue_action method"
177187
kind: "breaking"

0 commit comments

Comments
 (0)