kataras/iris · error

no trailing path parameter found

Error message

no trailing path parameter found

What it means

This error is raised by parsePathParam in the MVC controller method-to-route parser when the path template uses a wildcard '{param:string ...}' marker but no trailing parameter type was actually registered before it. In practice it means the method signature/path combination implies a trailing wildcard parameter that does not exist.

Solutions

  1. Remove the stray wildcard token from the controller method's path template.
  2. Ensure the method has a trailing string parameter matching the wildcard, e.g. func (c *Controller) Get(path string).
  3. Register the route with the standard router (app.Handle) instead of MVC if exotic wildcard syntax is needed.

Example fix

// before
func (c *FileController) GetBy(path string, rest string) {} // path: /files/{p:string ...} with mismatched param

// after
func (c *FileController) GetByWildcard(path string) {} // single trailing param: /files/{path:string ...}
Defensive patterns

Strategy: validation

Validate before calling

// ensure every wildcard in an MVC path has exactly one trailing string param
// /files/{path:string ...} requires: func (c *Ctl) GetBy(path string)

Prevention

When it happens

Trigger: An MVC controller method is registered whose path ends with the wildcard token but whose parameter list does not define a matching trailing parameter (trailings slice is empty), so when the lexer peeks the wildcard token there is no trailing param to map.

Common situations: Hand-writing path templates with '...' or wildcard syntax on MVC controller methods; typos like '{param:string ...}' without the macro registering a trailing entry; refactoring method signatures and leaving stale wildcard syntax in the path.

Related errors


AI-assisted analysis of kataras/iris@7bedaf55a0 (2026-08-30). Data as JSON: /api/errors/d80727b8406de352. Report an issue: GitHub.

Appendix: source

Thrown at mvc/controller_method_parser.go:245

		// By found but input arguments are not there, so act like /by path without restricts.
		path = addPathWord(path, w)
		return path, funcArgPos, nil
	}

	var (
		paramKey  = genParamKey(funcArgPos) // argfirst, argsecond...
		m         = p.macros.GetMaster()    // default (String by-default)
		trailings = p.macros.GetTrailings()
	)

	// string, int...
	goType := typ.In(funcArgPos).Kind()
	nextWord := p.lexer.peekNext()

	if nextWord == tokenWildcard {
		p.lexer.skip() // skip the Wildcard word.
		if len(trailings) == 0 {
			return "", 0, errors.New("no trailing path parameter found")
		}
		m = trailings[0]
	} else {
		// validMacros := p.macros.LookupForGoType(goType)

		// instead of mapping with a reflect.Kind which has its limitation,
		// we map the param types with a go type as a string,
		// so custom structs such as "user" can be mapped to a macro with indent || alias == "user".
		m = p.macros.Get(strings.ToLower(goType.String()))

		if m == nil {
			if typ.NumIn() > funcArgPos {
				// has more input arguments but we are not in the correct
				// index now, maybe the first argument was an `iris/context.Context`
				// so retry with the "funcArgPos" incremented.
				//
				// the "funcArgPos" will be updated to the caller as well
				// because we return it among the path and the error.

View on GitHub (pinned to 7bedaf55a0)