gofr-dev/gofr · error

container is nil

Error message

container is nil

What it means

errContainerNil is returned by NewAPIKeyAuthProviderWithValidateFunc and NewBasicAuthProviderWithValidateFunc in GoFr's auth middleware when the *container.Container argument is nil. These constructor variants build validators that use datasources, which require a live container. Passing nil means the validate function could never resolve its dependencies.

Source

Thrown at pkg/gofr/http/middleware/auth.go:29

)

// AuthMethod represents a custom type to define the different authentication methods supported.
type AuthMethod int

const (
	JWTClaim AuthMethod = iota // JWTClaim represents the key used to store JWT claims within the request context.
	Username
	APIKey

	// #nosec G101
	headerXAPIKey       = "X-Api-Key"
	headerAuthorization = "Authorization"

	dummyValue = "dummy"
)

var (
	errContainerNil      = errors.New("container is nil")
	errValidateFuncEmpty = errors.New("validate func is empty")
)

// AuthHeaders returns the request header names GoFr's authentication middleware reads. It is the
// single source of truth for callers that must forward a request's identity — e.g. the MCP server
// re-dispatching a tool call through the router.
func AuthHeaders() []string {
	return []string{headerAuthorization, headerXAPIKey}
}

type AuthProvider interface {
	GetAuthMethod() AuthMethod
	ExtractAuthHeader(r *http.Request) (any, ErrorHTTP)
}

// AuthMiddleware creates a middleware function that enforces authentication based on the method provided.
func AuthMiddleware(a AuthProvider) func(handler http.Handler) http.Handler {
	return func(handler http.Handler) http.Handler {

View on GitHub (pinned to 187eb24962)

Solutions

  1. Create the container first (e.g. c := app.NewContainer()) and pass the non-nil pointer to the constructor
  2. Reorder middleware setup so it happens after container initialization
  3. In tests, build the container (e.g. container.NewContainer with mocks) before calling the constructor
  4. Guard with a nil check at the call site to surface the wiring bug early

Example fix

// before
provider, err := middleware.NewBasicAuthProviderWithValidateFunc(nil, myValidate) // errContainerNil
// after
c := app.NewContainer()
provider, err := middleware.NewBasicAuthProviderWithValidateFunc(c, myValidate)
Defensive patterns

Strategy: validation

Validate before calling

if c == nil {
    return errors.New("container must be initialized before creating auth providers")
}

Type guard

func containerReady(c *container.Container) bool { return c != nil }

Try / catch

provider, err := middleware.NewBasicAuthProviderWithValidateFunc(c, fn)
if err != nil {
    if errors.Is(err, middleware.ErrContainerNil) {
        log.Fatal("auth middleware created before container initialization")
    }
    return err
}

Prevention

When it happens

Trigger: Calling NewAPIKeyAuthProviderWithValidateFunc(nil, fn) or NewBasicAuthProviderWithValidateFunc(nil, fn), typically when the container hasn't been created yet or is lazily initialized after middleware setup.

Common situations: Constructing middleware in init()/package-level vars before app.NewContainer() runs, DI wiring mistakes in tests, or refactoring where the container variable is shadowed as nil.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/1e84ca07acc4d26c. Report an issue: GitHub.