caddyserver/caddy · error

more than 1 module passed in

Error message

more than 1 module passed in

What it means

Context.Logger is variadic only for backward compatibility; it accepts at most zero or one Module argument. Passing two or more modules is a caller bug (the extra arguments came from the deprecated Logger(module) form) and triggers an immediate panic.

Source

Thrown at context.go:575

// recent module associated with the context. Callers should not
// pass in any arguments unless they want to associate with a
// different module; it panics if more than 1 value is passed in.
//
// Originally, this method's signature was `Logger(mod Module)`,
// requiring that an instance of a Caddy module be passed in.
// However, that is no longer necessary, as the closest module
// most recently associated with the context will be automatically
// assumed. To prevent a sudden breaking change, this method's
// signature has been changed to be variadic, but we may remove
// the parameter altogether in the future. Callers should not
// pass in any argument. If there is valid need to specify a
// different module, please open an issue to discuss.
//
// PARTIALLY DEPRECATED: The Logger(module) form is deprecated and
// may be removed in the future. Do not pass in any arguments.
func (ctx Context) Logger(module ...Module) *zap.Logger {
	if len(module) > 1 {
		panic("more than 1 module passed in")
	}
	if ctx.cfg == nil {
		// often the case in tests; just use a dev logger
		l, err := zap.NewDevelopment()
		if err != nil {
			panic("config missing, unable to create dev logger: " + err.Error())
		}
		return l
	}
	mod := ctx.Module()
	if len(module) > 0 {
		mod = module[0]
	}
	if mod == nil {
		return Log()
	}
	return ctx.cfg.Logging.Logger(mod)
}

View on GitHub (pinned to 50e54ee279)

Solutions

  1. Pass no argument: ctx.Logger() — the context's own module is used automatically
  2. If you must override, pass exactly one module: ctx.Logger(mod)
  3. Never splat a slice into Logger; select a single element first

Example fix

// before
logger := ctx.Logger(modA, modB)
// after
logger := ctx.Logger()
Defensive patterns

Strategy: validation

Validate before calling

if len(modules) > 1 {
    return nil, fmt.Errorf("Logger accepts at most one module, got %d", len(modules))
}
logger := ctx.Logger(modules...)

Prevention

When it happens

Trigger: Calling ctx.Logger(modA, modB) — any call with len(module) > 1.

Common situations: Migrating old code that called Logger(mod) and accidentally splatting a slice: ctx.Logger(mods...); grep-and-replace introducing multiple arguments; IDE autocompletion adding extra params.

Related errors


AI-assisted analysis of caddyserver/caddy@50e54ee279 (2026-08-15). Data as JSON: /api/errors/c3978f14a6e9f136. Report an issue: GitHub.