gin-gonic/gin · error

wildcards must be named with a non-empty name in path '${ful

Error message

wildcards must be named with a non-empty name in path '${fullPath}'

What it means

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.

Source

Thrown at tree.go:304

}

func (n *node) insertChild(path string, fullPath string, handlers HandlersChain) {
	for {
		// Find prefix until first wildcard
		wildcard, i, valid := findWildcard(path)
		if i < 0 { // No wildcard found
			break
		}

		// The wildcard name must only contain one ':' or '*' character
		if !valid {
			panic("only one wildcard per path segment is allowed, has: '" +
				wildcard + "' in path '" + fullPath + "'")
		}

		// check if the wildcard has a name
		if len(wildcard) < 2 {
			panic("wildcards must be named with a non-empty name in path '" + fullPath + "'")
		}

		if wildcard[0] == ':' { // param
			if i > 0 {
				// Insert prefix before the current wildcard
				n.path = path[:i]
				path = path[i:]
			}

			child := &node{
				nType:    param,
				path:     wildcard,
				fullPath: fullPath,
			}
			n.addChild(child)
			n.wildChild = true
			n = child
			n.priority++

View on GitHub (pinned to 34dac209ff)

Solutions

  1. Give every wildcard a descriptive name: /users/:userID, /static/*filepath.
  2. If you do not actually need the value, use a static segment instead — '/users' rather than '/users/:'.
  3. Lint route definitions for the regex /:[^/]*$/ or /\*/?$ to catch empty names in CI.

Example fix

// before
router.GET("/users/:", h)        // panics: empty param name
router.GET("/static/*", h)       // panics: empty catch-all name

// after
router.GET("/users/:userID", h)
router.GET("/static/*filepath", h)
Defensive patterns

Strategy: validation

Validate before calling

// Reject wildcards with empty names: /:  /: /  /*  /*/
var emptyWildcard = regexp.MustCompile(`(/:[^/]*)|(/\*)`)

func validateWildcardNames(p string) error {
    for _, seg := range strings.Split(p, "/") {
        if (strings.HasPrefix(seg, ":") || strings.HasPrefix(seg, "*")) && len(seg)  2 {
            return fmt.Errorf("wildcard %q in path %q has no name", seg, p)
        }
    }
    return nil
}

Try / catch

func safeRegister(e *gin.Engine, method, path string, h gin.HandlerFunc) (err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("empty wildcard name in %s: %v", path, r)
        }
    }()
    e.Handle(method, path, h)
    return nil
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of gin-gonic/gin@34dac209ff (2026-08-04). Data as JSON: /data/errors/fce24ef88cc0f4d4.json. Report an issue: GitHub.