{"record":{"id":"74cc651bc3e48ed3","repo":"kataras/iris","slug":"pool-cannot-be-nil","errorCode":null,"errorMessage":"pool cannot be nil","messagePattern":"pool cannot be nil","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"context_wrapper.go","lineNumber":120,"sourceCode":"// ContextWrapper is a wrapper for handlers which expect a T instead of iris.Context.\n//\n// See the `NewContextWrapper` function for more.\ntype ContextWrapper[T any] struct {\n\tpool ContextPool[T]\n}\n\n// NewContextWrapper returns a new ContextWrapper.\n// If pool is nil, a default pool is used.\n// The default pool's AcquireFunc returns a zero value of T.\n// The default pool's ReleaseFunc does nothing.\n// The default pool is used when the pool is nil.\n// Use the `iris.NewContextPool[T, *T]()` to pass a simple context pool.\n// Then, use the `Handler` method to wrap custom handlers to iris ones.\n//\n// Example: https://github.com/kataras/iris/tree/main/_examples/routing/custom-context\nfunc NewContextWrapper[T any](pool ContextPool[T]) *ContextWrapper[T] {\n\tif pool == nil {\n\t\tpanic(\"pool cannot be nil\")\n\t}\n\n\treturn &ContextWrapper[T]{\n\t\tpool: pool,\n\t}\n}\n\n// Pool returns the pool, useful when manually Acquire and Release of custom context is required.\nfunc (w *ContextWrapper[T]) Pool() ContextPool[T] {\n\treturn w.pool\n}\n\n// Handler wraps the handler with the pool's Acquire and Release methods.\n// It returns a new handler which expects a T instead of iris.Context.\n// The T is the type of the pool.\n// The T is acquired from the pool and released back to the pool after the handler's execution.\n// The T is passed to the handler as an argument.\n// The T is not shared between requests.","sourceCodeStart":102,"sourceCodeEnd":138,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/context_wrapper.go#L102-L138","documentation":"NewContextWrapper wraps a generic ContextPool[T] so custom context types can be used as Iris handlers. The library panics immediately at construction if the pool argument is nil, because the wrapper cannot function without a pool to acquire/release contexts. It is a fail-fast guard against a misconfigured generic wrapper.","triggerScenarios":"Calling iris.NewContextWrapper[T](nil), or passing a nil interface variable that was declared as ContextPool[T] but never assigned an implementation (e.g. the result of an uninitialized or failed iris.NewContextPool[T, *T]() call assigned to a nil-typed variable).","commonSituations":"Declaring `var pool iris.ContextPool[MyContext]` at package level and forgetting to initialize it before building routes; copying example code from the custom-context example and omitting the NewContextPool step; refactoring where pool construction was moved behind a flag or error path that silently skipped it.","solutions":["Create the pool with iris.NewContextPool[T, *T]() and pass it to NewContextWrapper","Ensure the variable holding the pool is initialized before route registration, not just declared","If the pool comes from another function, check it for nil before calling NewContextWrapper"],"exampleFix":"// before\nvar pool iris.ContextPool[MyContext]\nw := iris.NewContextWrapper(pool) // panics: pool cannot be nil\n// after\npool := iris.NewContextPool[MyContext, *MyContext]()\nw := iris.NewContextWrapper(pool)","handlingStrategy":"validation","validationCode":"func safeNewContextWrapper[T any](pool iris.ContextPool[T]) *iris.ContextWrapper[T] {\n    if pool == nil {\n        pool = iris.NewContextPool[T, *T]()\n    }\n    return iris.NewContextWrapper(pool)\n}","typeGuard":"func isNilPool[T any](pool iris.ContextPool[T]) bool {\n    return pool == nil\n}","tryCatchPattern":"// Go panics are not catchable idiomatically per-call; guard at startup:\nfunc mustWrapper[T any](pool iris.ContextPool[T]) (w *iris.ContextWrapper[T]) {\n    defer func() {\n        if r := recover(); r != nil {\n            log.Fatalf(\"NewContextWrapper failed: %v\", r)\n        }\n    }()\n    return iris.NewContextWrapper(pool)\n}","preventionTips":["Always construct the pool with iris.NewContextPool[T, *T]() immediately before NewContextWrapper","Avoid package-level `var pool ContextPool[T]` declarations without initialization","Initialize the wrapper once at startup inside a must-style helper that fails fast with a clear log"],"tags":["panic","nil-argument","routing","generics"],"backgroundTag":"nil-argument-panic","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}