gin-gonic/gin · error

too many parameters

Error message

too many parameters

What it means

Thrown by resolveAddress in utils.go:159 when Engine.Run is called with more than one address argument. resolveAddress accepts a variadic addr []string but only knows how to choose a single bind address: zero args means 'use $PORT or :8080', one arg means 'use it literally', and two or more is ambiguous so it panics. Run, RunListener-related helpers, and any caller that forwards a variadic address list into resolveAddress can trigger it.

Source

Thrown at utils.go:159

	if lastChar(relativePath) == '/' && lastChar(finalPath) != '/' {
		return finalPath + "/"
	}
	return finalPath
}

func resolveAddress(addr []string) string {
	switch len(addr) {
	case 0:
		if port := os.Getenv("PORT"); port != "" {
			debugPrint("Environment variable PORT=\"%s\"", port)
			return ":" + port
		}
		debugPrint("Environment variable PORT is undefined. Using port :8080 by default")
		return ":8080"
	case 1:
		return addr[0]
	default:
		panic("too many parameters")
	}
}

// https://stackoverflow.com/questions/53069040/checking-a-string-contains-only-ascii-characters
func isASCII(s string) bool {
	for i := range len(s) {
		if s[i] > unicode.MaxASCII {
			return false
		}
	}
	return true
}

// safeInt8 converts int to int8 safely, capping at math.MaxInt8
func safeInt8(n int) int8 {
	if n > math.MaxInt8 {
		return math.MaxInt8
	}

View on GitHub (pinned to 34dac209ff)

Solutions

  1. Pass at most one address: r.Run(":8080") or r.Run() to use $PORT / :8080.
  2. If you have a slice of unknown length, take the first element explicitly: r.Run(addrs[0]) after checking len(addrs) >= 1.
  3. For multi-address or TLS setups, run the listeners manually: start one goroutine per address with r.Run / r.RunTLS / r.RunListener, or use http.Server with Engine as handler.

Example fix

// before
r.Run(":8080", ":8081") // panics: too many parameters

// after — single address
r.Run(":8080")

// multi-address — separate goroutines
go func() { _ = r.Run(":8080") }()
r.RunTLS(":8443", "cert.pem", "key.pem")
Defensive patterns

Strategy: validation

Validate before calling

// Validate the variadic address slice before forwarding it to Engine.Run.
func resolveAddrSafe(addr []string) (string, error) {
    switch len(addr) {
    case 0:
        return ":8080", nil // or read $PORT
    case 1:
        return addr[0], nil
    default:
        return "", fmt.Errorf("too many addresses (%d); pass at most one to Run", len(addr))
    }
}

// usage
addr, err := resolveAddrSafe(addrs)
if err != nil { log.Fatal(err) }
_ = r.Run(addr)

Try / catch

func runSafe(e *gin.Engine, addr ...string) (err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("Run(%v): %v", addr, r)
        }
    }()
    return e.Run(addr...)
}

Prevention

When it happens

Trigger: Calling r.Run(":8080", ":8081"), r.Run(addr1, addr2), or forwarding a variadic []string of unknown length into Run, e.g. r.Run(args...) where len(args) > 1.

Common situations: Refactoring a main() that used to flag-parse a single address and accidentally passing two; forwarding os.Args or a CLI library's string slice directly into Run; copy-pasting a dual-stack (TCP + TLS) pattern into a single Run call instead of using Run + RunTLS separately.

Related errors


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