gorilla/mux · error
mux: missing route variable %q
Error message
mux: missing route variable %q
What it means
Returned by routeRegexp.url() (regexp.go:217) during reverse URL building via Route.URL/URLPath/URLHost when a named placeholder declared in the route template has no entry in the supplied pairs. gorilla/mux treats every {...} variable as required, so omitting any one aborts URL construction and surfaces the missing variable name in the message.
Source
Thrown at regexp.go:217
}
if r.regexpType == regexpTypeQuery {
return r.matchQueryString(req)
}
path := req.URL.Path
if r.options.useEncodedPath {
path = req.URL.EscapedPath()
}
return r.regexp.MatchString(path)
}
// url builds a URL part using the given values.
func (r *routeRegexp) url(values map[string]string) (string, error) {
urlValues := make([]interface{}, len(r.varsN))
for k, v := range r.varsN {
value, ok := values[v]
if !ok {
return "", fmt.Errorf("mux: missing route variable %q", v)
}
if r.regexpType == regexpTypeQuery {
value = url.QueryEscape(value)
}
urlValues[k] = value
}
rv := fmt.Sprintf(r.reverse, urlValues...)
if !r.regexp.MatchString(rv) {
// The URL is checked against the full regexp, instead of checking
// individual variables. This is faster but to provide a good error
// message, we check individual regexps if the URL doesn't match.
for k, v := range r.varsN {
if !r.varsR[k].MatchString(values[v]) {
return "", fmt.Errorf(
"mux: variable %q doesn't match, expected %q", values[v],
r.varsR[k].String())
}
}View on GitHub (pinned to db9d1d0073)
Solutions
- Read the variable name in the error message (the %q) and add the corresponding "name", "value" pair to the URL/URLPath/URLHost call.
- Cross-check against r.GetPathTemplate() (or GetHostTemplate) to enumerate every required variable before constructing the URL.
- Wrap URL() construction in a helper that takes a map[string]string and asserts it covers GetPathTemplate()'s variables, failing loudly at startup.
- If the variable is genuinely optional, split the route into two routes (one with, one without the segment) instead of trying to omit it.
Example fix
// before: route is /articles/{category}/{id:[0-9]+}
url, err := r.Get("article").URL("category", "tech")
// err: mux: missing route variable "id"
// after
url, err := r.Get("article").URL("category", "tech", "id", "42") Defensive patterns
Strategy: validation
Validate before calling
// Validate before calling Route.URL / URLPath / URLHost
tpl, err := r.Get("article").GetPathTemplate()
if err != nil { return err }
required := routeVarNames(tpl) // parses {name} and {name:pat} out of tpl
provided := map[string]string{"category": cat, "id": id} // your pairs
for _, name := range required {
if _, ok := provided[name]; !ok {
return fmt.Errorf("missing route variable %q", name)
}
}
return nil
// helper
func routeVarNames(tpl string) []string {
var out []string
for i := 0; i < len(tpl); i++ {
if tpl[i] != '{' { continue }
j := strings.IndexByte(tpl[i:], '}')
if j < 0 { break }
body := tpl[i+1 : i+j]
if c := strings.IndexByte(body, ':'); c >= 0 { body = body[:c] }
out = append(out, body)
i += j
}
return out
} Try / catch
// Go: check the returned error, don't ignore it.
u, err := r.Get("article").URL("category", cat, "id", id)
if err != nil {
// err.Error() is exactly: mux: missing route variable %q
var name string
if _, gerr := fmt.Sscanf(err.Error(), "mux: missing route variable %q", &name); gerr == nil {
return fmt.Errorf("cannot build URL: required variable %s not supplied", name)
}
return err
}
return u Prevention
- Never ignore the error returned by Route.URL / URLPath / URLHost.
- Centralize URL building per route in a typed helper whose signature lists every variable, so the compiler enforces completeness.
- When you add or rename a {var} in a route template, grep for every URL()/URLPath()/URLHost() call on that named route the same commit.
- Add a startup test that constructs URLs for every named route with sample values so a missing variable fails CI, not production.
When it happens
Trigger: Calling r.Get("article").URL("category", "tech") for a route registered as Path("/articles/{category}/{id:[0-9]+}") — id is missing. Same for URLPath/URLHost when the host/path template declares more variables than the caller passes.
Common situations: A new {var} was added to a route template but an existing URL() call site wasn't updated; a variable was renamed; key/value pairs were passed in the wrong even/odd order so a value landed where a key was expected; refactor moved URL building into a helper that dropped a pair.
Related errors
- mux: variable %q doesn't match, expected %q
- mux: route doesn't have a host
- mux: route doesn't have a path
- mux: unbalanced braces in %q
- method is not allowed
AI-assisted analysis of gorilla/mux@db9d1d0073 (2026-08-04).
Data as JSON: /data/errors/5943f76607a86dd4.json.
Report an issue: GitHub.