← Debugging Guides

阅读中文版本

Gin — panic on duplicate route or wildcard conflict

Fix Gin routing panics by removing conflicting paths and using consistent wildcard parameters.

beginnerdebugginggogin

Symptoms

  • panic: route /users/:id conflicts with existing wildcard
  • The server panics at startup when registering routes
  • Two routes differ only in parameter names
  • A static path collides with a parameter path

Possible causes

  • Two routes use different parameter names at the same position
  • A static segment conflicts with a wildcard at the same level
  • Routes are registered twice, for example in two init blocks
  • A catch-all conflicts with a specific prefix

Diagnosis steps

Read the conflicting paths

go test ./... 2>&1 | grep -i "panic\|conflict"

Interpretation

The panic names both routes, showing which pair conflicts and at which segment.

Unify parameter names

grep -rn ":id\|:userID" main.go routes/*.go

Interpretation

The same position must use the same parameter name across routes; differing names are a common conflict.

Look for duplicate registration

grep -rn "router.GET\|router.POST" main.go routes/*.go

Interpretation

Registering the same method and path twice triggers the panic, often from copy-paste or multiple setup functions.

Root cause

The router could not build a consistent tree because two routes disagreed at the same position, either through different parameter names, duplicate registration or a wildcard colliding with a static segment.

Fix

Use identical parameter names for the same path position, remove duplicate registrations, and ensure wildcards and catch-alls do not overlap with concrete routes.

Verify the fix

Start the server and confirm it does not panic, then call each affected route and confirm it matches the intended handler.

Symptom walkthrough

Registering routes makes the server panic at startup with a message about a route conflicting with an existing wildcard. Gin builds a radix tree for routing, so two routes that disagree at the same segment cannot both exist. Different parameter names at one position, a static path under a wildcard, or a route registered twice are the usual causes.

Fix in practice

Make the same position use one parameter name everywhere, remove duplicate registrations, and keep wildcard and catch-all patterns from overlapping concrete routes. Fixing the tree so every branch is unambiguous lets the server start.

Verification

Start the server and confirm it no longer panics, then request each affected path and confirm it hits the intended handler. Correct startup plus correct routing confirms the fix. A startup test that builds the router catches conflicts before they reach deployment.

Diagnostic commands

Check the behavior with commands like these:

go test ./... 2>&1 | grep -i "panic\|conflict"
grep -rn ":id\|:userID" main.go routes/*.go
grep -rn "router.GET\|router.POST" main.go routes/*.go