{"id":"fce24ef88cc0f4d4","repo":"gin-gonic/gin","slug":"wildcards-must-be-named-with-a-non-empty-name-in-p","errorCode":null,"errorMessage":"wildcards must be named with a non-empty name in path '${fullPath}'","messagePattern":"wildcards must be named with a non-empty name in path '(.+?)'","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"tree.go","lineNumber":304,"sourceCode":"}\n\nfunc (n *node) insertChild(path string, fullPath string, handlers HandlersChain) {\n\tfor {\n\t\t// Find prefix until first wildcard\n\t\twildcard, i, valid := findWildcard(path)\n\t\tif i < 0 { // No wildcard found\n\t\t\tbreak\n\t\t}\n\n\t\t// The wildcard name must only contain one ':' or '*' character\n\t\tif !valid {\n\t\t\tpanic(\"only one wildcard per path segment is allowed, has: '\" +\n\t\t\t\twildcard + \"' in path '\" + fullPath + \"'\")\n\t\t}\n\n\t\t// check if the wildcard has a name\n\t\tif len(wildcard) < 2 {\n\t\t\tpanic(\"wildcards must be named with a non-empty name in path '\" + fullPath + \"'\")\n\t\t}\n\n\t\tif wildcard[0] == ':' { // param\n\t\t\tif i > 0 {\n\t\t\t\t// Insert prefix before the current wildcard\n\t\t\t\tn.path = path[:i]\n\t\t\t\tpath = path[i:]\n\t\t\t}\n\n\t\t\tchild := &node{\n\t\t\t\tnType:    param,\n\t\t\t\tpath:     wildcard,\n\t\t\t\tfullPath: fullPath,\n\t\t\t}\n\t\t\tn.addChild(child)\n\t\t\tn.wildChild = true\n\t\t\tn = child\n\t\t\tn.priority++","sourceCodeStart":286,"sourceCodeEnd":322,"githubUrl":"https://github.com/gin-gonic/gin/blob/34dac209ffb6ef85cc78c5d217bbb7ad001d68fd/tree.go#L286-L322","documentation":"Thrown by (*node).insertChild in tree.go:304 when findWildcard returns a marker character (':' or '*') with no name following it, i.e. len(wildcard) < 2. A param or catch-all must carry a non-empty name so that handlers can read it via c.Param(\"name\"). Routes like /users:/ or /files/* are rejected. The full path is included in the message.","triggerScenarios":"Registering /users/: (param with empty name), /static/* (catch-all with no name), or a path ending in a bare ':' like /search:. Also triggered by typos such as /: /:id where the colon is meant to start a name but is left alone.","commonSituations":"Typing a route quickly and forgetting the parameter name; refactoring that strips a name but leaves the ':'; generating routes from a template that emits ':' with an empty placeholder.","solutions":["Give every wildcard a descriptive name: /users/:userID, /static/*filepath.","If you do not actually need the value, use a static segment instead — '/users' rather than '/users/:'.","Lint route definitions for the regex /:[^/]*$/ or /\\*/?$ to catch empty names in CI."],"exampleFix":"// before\nrouter.GET(\"/users/:\", h)        // panics: empty param name\nrouter.GET(\"/static/*\", h)       // panics: empty catch-all name\n\n// after\nrouter.GET(\"/users/:userID\", h)\nrouter.GET(\"/static/*filepath\", h)","handlingStrategy":"validation","validationCode":"// Reject wildcards with empty names: /:  /: /  /*  /*/\nvar emptyWildcard = regexp.MustCompile(`(/:[^/]*)|(/\\*)`)\n\nfunc validateWildcardNames(p string) error {\n    for _, seg := range strings.Split(p, \"/\") {\n        if (strings.HasPrefix(seg, \":\") || strings.HasPrefix(seg, \"*\")) && len(seg) \u0001 2 {\n            return fmt.Errorf(\"wildcard %q in path %q has no name\", seg, p)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":"func safeRegister(e *gin.Engine, method, path string, h gin.HandlerFunc) (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"empty wildcard name in %s: %v\", path, r)\n        }\n    }()\n    e.Handle(method, path, h)\n    return nil\n}","preventionTips":["Always pair a marker with a descriptive name: ':userID', '*filepath'.","If you do not need the value, make the segment static.","Add a CI regex check that rejects routes ending in a bare ':' or containing '/*' not followed by a name."],"tags":["routing","invalid-path","wildcard","gin","startup-panic"],"analyzedSha":"34dac209ffb6ef85cc78c5d217bbb7ad001d68fd","analyzedAt":"2026-08-04T21:26:18.438Z","schemaVersion":2}