gorilla/mux · error

mux: number of parameters must be multiple of 2, got %v

Error message

mux: number of parameters must be multiple of 2, got %v

What it means

Returned by checkPairs (mux.go:563-569) when the variadic string pairs passed to a key/value matcher are odd (a key missing its value). It propagates through mapFromPairsToString / mapFromPairsToRegex into Headers, HeadersRegexp, and prepareVars (used by URL/URLHost/URLPath), and is stored on r.err.

Source

Thrown at mux.go:566

// uniqueVars returns an error if two slices contain duplicated strings.
func uniqueVars(s1, s2 []string) error {
	for _, v1 := range s1 {
		for _, v2 := range s2 {
			if v1 == v2 {
				return fmt.Errorf("mux: duplicated route variable %q", v2)
			}
		}
	}
	return nil
}

// checkPairs returns the count of strings passed in, and an error if
// the count is not an even number.
func checkPairs(pairs ...string) (int, error) {
	length := len(pairs)
	if length%2 != 0 {
		return length, fmt.Errorf(
			"mux: number of parameters must be multiple of 2, got %v", pairs)
	}
	return length, nil
}

// mapFromPairsToString converts variadic string parameters to a
// string to string map.
func mapFromPairsToString(pairs ...string) (map[string]string, error) {
	length, err := checkPairs(pairs...)
	if err != nil {
		return nil, err
	}
	m := make(map[string]string, length/2)
	for i := 0; i < length; i += 2 {
		m[pairs[i]] = pairs[i+1]
	}
	return m, nil
}

View on GitHub (pinned to db9d1d0073)

Solutions

  1. Ensure Headers/HeadersRegexp/URL-style calls always pass an even number of args.
  2. Build the pairs slice explicitly and assert len%2 == 0 before calling.
  3. Check route.GetError() right after construction to surface the failure.

Example fix

// before
r.Headers("Content-Type", "application/json", "X-Trace")
// odd number of args -> r.err set

// after
r.Headers("Content-Type", "application/json", "X-Trace", "")
Defensive patterns

Strategy: validation

Validate before calling

func evenPairs(pairs ...string) error {
    if len(pairs)%2 != 0 {
        return fmt.Errorf("odd pair count: %d", len(pairs))
    }
    return nil
}

Type guard

func validHeadersCall(pairs ...string) bool { return len(pairs)%2 == 0 }

Try / catch

rt := r.Headers(pairs...)
if err := rt.GetError(); err != nil {
    return err
}

Prevention

When it happens

Trigger: r.Headers("Content-Type", "application/json", "X-Trace") (3 args), or r.Get("x").URL("id", "42", "extra") (3 args to URL which routes through prepareVars).

Common situations: Dropping a value while editing a Headers call; passing a slice unpacked with pairs... whose length is odd; misreading the key,value,key,value contract.

Related errors


AI-assisted analysis of gorilla/mux@db9d1d0073 (2026-08-04). Data as JSON: /data/errors/f56f56fc48a2c976.json. Report an issue: GitHub.