kataras/iris · error

bad value: second output should be an error

Error message

bad value: second output should be an error

What it means

When a dependency function returns exactly two values, the second must implement the error interface so the container can short-circuit on failure. Returning two values where the second is not an error is rejected.

Source

Thrown at hero/dependency.go:295

	if numIn == 0 {
		// it's an empty function, that must return a structure.
		if numOut != 1 {
			firstOutType := indirectType(typ.Out(0))
			if firstOutType.Kind() != reflect.Struct && firstOutType.Kind() != reflect.Interface {
				panic(fmt.Sprintf("bad value: function has zero inputs: empty input function must output a single value but got: length=%v, type[0]=%s", numOut, firstOutType.String()))
			}
		}

		// fallback to structure.
		return fromStructValue(v.Call(nil)[0], dest)
	}

	if numOut == 0 {
		panic("bad value: function has zero outputs")
	}

	if numOut == 2 && !isError(typ.Out(1)) {
		panic("bad value: second output should be an error")
	}

	if numOut > 2 {
		// - at least one output value
		// - maximum of two output values
		// - second output value should be a type of error.
		panic(fmt.Sprintf("bad value: function has invalid number of output arguments: %v", numOut))
	}

	var handler DependencyHandler

	firstIsContext := isContext(typ.In(0))
	secondIsInput := numIn == 2 && typ.In(1) == inputTyp
	onlyContext := (numIn == 1 && firstIsContext) || (numIn == 2 && firstIsContext && typ.IsVariadic())

	if onlyContext || (firstIsContext && secondIsInput) {
		handler = handlerFromFunc(v, typ)
	}

View on GitHub (pinned to 7bedaf55a0)

Solutions

  1. Make the second return value of type error: func() (*Svc, error).
  2. If you need two non-error outputs, return a struct combining them: type Pair struct{ A A; B B }.
  3. Ensure the second type actually implements error (has an Error() string method), or use the standard error interface.

Example fix

// before
func newPair() (A, B) { ... }
c.Register(newPair)
// after
func newPair() (*Pair, error) { p, err := build(); return p, err }
// with type Pair struct { A A; B B }
Defensive patterns

Strategy: validation

Validate before calling

func secondOutIsError(fn any) bool {
	t := reflect.TypeOf(fn)
	return t.NumOut() != 2 || t.Out(1).Implements(errType)
}
var errType = reflect.TypeOf((*error)(nil)).Elem()

Prevention

When it happens

Trigger: Registering a function like func() (*Svc, *Result) or func(db *DB) (A, B) where the second return type is not error, via c.Register/NewDependency.

Common situations: Multi-value factories where the author meant to return two dependencies (not supported); a custom error-like type that does not implement error; accidentally swapped return order (error first).

Related errors


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