{"record":{"id":"a59dd8d62a7133b9","repo":"kataras/iris","slug":"remove-handler-unexpected-type-of-t","errorCode":null,"errorMessage":"remove handler: unexpected type of %T","messagePattern":"remove handler: unexpected type of %T","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/router/api_builder.go","lineNumber":1417,"sourceCode":"// then this is used to set the total amount of removed handlers.\n//\n// Returns the Party itself for chain calls.\n//\n// Should be called before children routes regitration.\nfunc (api *APIBuilder) RemoveHandler(namesOrHandlers ...any) Party {\n\tvar counter *int\n\n\tfor _, nameOrHandler := range namesOrHandlers {\n\t\thandlerName := \"\"\n\t\tswitch h := nameOrHandler.(type) {\n\t\tcase string:\n\t\t\thandlerName = h\n\t\tcase context.Handler: //, func(*context.Context):\n\t\t\thandlerName = context.HandlerName(h)\n\t\tcase *int:\n\t\t\tcounter = h\n\t\tdefault:\n\t\t\tpanic(fmt.Sprintf(\"remove handler: unexpected type of %T\", h))\n\t\t}\n\n\t\tapi.middleware = removeHandler(handlerName, api.middleware, counter)\n\t\tapi.doneHandlers = removeHandler(handlerName, api.doneHandlers, counter)\n\t}\n\n\treturn api\n}\n\n// Reset removes all the begin and done handlers that may derived from the parent party via `Use` & `Done`,\n// and the execution rules.\n// Note that the `Reset` will not reset the handlers that are registered via `UseGlobal` & `DoneGlobal`.\n//\n// Returns this Party.\nfunc (api *APIBuilder) Reset() Party {\n\tapi.middleware = api.middleware[0:0]\n\tapi.middlewareErrorCode = api.middlewareErrorCode[0:0]\n\tapi.ResetRouterFilters()","sourceCodeStart":1399,"sourceCodeEnd":1435,"githubUrl":"https://github.com/kataras/iris/blob/7bedaf55a0b64bbb2248a5845a2c60d81a30996a/core/router/api_builder.go#L1399-L1435","documentation":"APIBuilder.RemoveHandler accepts only string (handler name) or context.Handler values to identify which middleware/handler to remove. Any other argument type reaches the default branch of the type switch and panics with the offending Go type (%T). It is a compile-time-absent type safety check done at runtime via a type switch.","triggerScenarios":"Calling Party/APIBuilder RemoveHandler (or RemoveHandler-ish API at api_builder.go) with an unsupported value, e.g. a func(iris.Context) literal (not typed as context.Handler), an int used as counter without *int, a *context.Handler, or any other arbitrary value.","commonSituations":"Passing an untyped function literal `func(ctx *context.Context){...}` instead of an iris/context.Handler; passing `count` (int) instead of `&count` (*int) as the occurrence counter; refactoring code that previously removed handlers by name.","solutions":["Pass a string handler name or a value of type context.Handler","If using the occurrence counter, pass a *int (e.g. &count), not an int","Convert function literals to context.Handler, e.g. context.Handler(myFunc) or use the named handler registration"],"exampleFix":"// before\napp.RemoveHandler(func(ctx *iris.Context) { ... }) // panics: unexpected type\n// after\napp.RemoveHandler(iris.Context.Handler(myHandler)) // or\napp.RemoveHandler(\"myHandlerName\")","handlingStrategy":"type-guard","validationCode":"func canRemoveHandler(v any) bool {\n    switch v.(type) {\n    case string, context.Handler:\n        return true\n    default:\n        return false\n    }\n}","typeGuard":"func isRemoveHandlerArg(v any) bool {\n    switch v.(type) {\n    case string:\n        return true\n    case context.Handler:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"func removeHandlerSafe(api *iris.APIBuilder, arg any) {\n    defer func() {\n        if r := recover(); r != nil {\n            log.Printf(\"RemoveHandler panicked: %v (arg %T)\", r, arg)\n        }\n    }()\n    if !isRemoveHandlerArg(arg) {\n        log.Printf(\"skip: unsupported arg type %T\", arg)\n        return\n    }\n    api.RemoveHandler(arg)\n}","preventionTips":["Always pass handler names as string or handlers typed as iris/context.Handler","Convert plain funcs with context.Handler(fn) before removal","Remember the builder-level API accepts *int counters — pass &count, not count","Prefer removing by registered handler name for stability across refactors"],"tags":["panic","type-mismatch","routing","middleware"],"backgroundTag":"unsupported-argument-type","analyzedSha":"7bedaf55a0b64bbb2248a5845a2c60d81a30996a","analyzedAt":"2026-08-30T20:38:16.250Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}