{"record":{"id":"1e84ca07acc4d26c","repo":"gofr-dev/gofr","slug":"container-is-nil","errorCode":null,"errorMessage":"container is nil","messagePattern":"container is nil","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/gofr/http/middleware/auth.go","lineNumber":29,"sourceCode":")\n\n// AuthMethod represents a custom type to define the different authentication methods supported.\ntype AuthMethod int\n\nconst (\n\tJWTClaim AuthMethod = iota // JWTClaim represents the key used to store JWT claims within the request context.\n\tUsername\n\tAPIKey\n\n\t// #nosec G101\n\theaderXAPIKey       = \"X-Api-Key\"\n\theaderAuthorization = \"Authorization\"\n\n\tdummyValue = \"dummy\"\n)\n\nvar (\n\terrContainerNil      = errors.New(\"container is nil\")\n\terrValidateFuncEmpty = errors.New(\"validate func is empty\")\n)\n\n// AuthHeaders returns the request header names GoFr's authentication middleware reads. It is the\n// single source of truth for callers that must forward a request's identity — e.g. the MCP server\n// re-dispatching a tool call through the router.\nfunc AuthHeaders() []string {\n\treturn []string{headerAuthorization, headerXAPIKey}\n}\n\ntype AuthProvider interface {\n\tGetAuthMethod() AuthMethod\n\tExtractAuthHeader(r *http.Request) (any, ErrorHTTP)\n}\n\n// AuthMiddleware creates a middleware function that enforces authentication based on the method provided.\nfunc AuthMiddleware(a AuthProvider) func(handler http.Handler) http.Handler {\n\treturn func(handler http.Handler) http.Handler {","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/gofr-dev/gofr/blob/187eb24962502e91f1fee856230670958b66e89c/pkg/gofr/http/middleware/auth.go#L11-L47","documentation":"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.","triggerScenarios":"Calling NewAPIKeyAuthProviderWithValidateFunc(nil, fn) or NewBasicAuthProviderWithValidateFunc(nil, fn), typically when the container hasn't been created yet or is lazily initialized after middleware setup.","commonSituations":"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.","solutions":["Create the container first (e.g. c := app.NewContainer()) and pass the non-nil pointer to the constructor","Reorder middleware setup so it happens after container initialization","In tests, build the container (e.g. container.NewContainer with mocks) before calling the constructor","Guard with a nil check at the call site to surface the wiring bug early"],"exampleFix":"// before\nprovider, err := middleware.NewBasicAuthProviderWithValidateFunc(nil, myValidate) // errContainerNil\n// after\nc := app.NewContainer()\nprovider, err := middleware.NewBasicAuthProviderWithValidateFunc(c, myValidate)","handlingStrategy":"validation","validationCode":"if c == nil {\n    return errors.New(\"container must be initialized before creating auth providers\")\n}","typeGuard":"func containerReady(c *container.Container) bool { return c != nil }","tryCatchPattern":"provider, err := middleware.NewBasicAuthProviderWithValidateFunc(c, fn)\nif err != nil {\n    if errors.Is(err, middleware.ErrContainerNil) {\n        log.Fatal(\"auth middleware created before container initialization\")\n    }\n    return err\n}","preventionTips":["Initialize the container before registering any middleware","Avoid package-level constructors that run before app bootstrap","In tests, construct a real/mocked container, not nil","Add a startup assertion that the container is non-nil where providers are built"],"tags":["auth","nil-pointer","container","gofr"],"backgroundTag":"nil-dependency-injection","analyzedSha":"187eb24962502e91f1fee856230670958b66e89c","analyzedAt":"2026-09-01T20:34:54.554Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}