{"record":{"id":"5ea109999bc48fba","repo":"router-for-me/CLIProxyAPI","slug":"management-registrar-panic-v","errorCode":null,"errorMessage":"management registrar panic: %v","messagePattern":"management registrar panic: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/pluginhost/management.go","lineNumber":107,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n\n\th.mu.Lock()\n\th.managementRoutes = nextRoutes\n\th.resourceRoutes = nextResources\n\th.mu.Unlock()\n}\n\nfunc (h *Host) callManagementRegistrar(ctx context.Context, record capabilityRecord, plugin pluginapi.ManagementAPI) (resp pluginapi.ManagementRegistrationResponse, err error) {\n\tif h == nil || plugin == nil || h.isPluginFused(record.id) || !h.recordCurrent(record) {\n\t\treturn pluginapi.ManagementRegistrationResponse{}, nil\n\t}\n\tdefer func() {\n\t\tif recovered := recover(); recovered != nil {\n\t\t\th.fusePlugin(record.id, \"ManagementAPI.RegisterManagement\", recovered)\n\t\t\tresp = pluginapi.ManagementRegistrationResponse{}\n\t\t\terr = fmt.Errorf(\"management registrar panic: %v\", recovered)\n\t\t}\n\t}()\n\treturn plugin.RegisterManagement(ctx, pluginapi.ManagementRegistrationRequest{\n\t\tPlugin:           record.meta,\n\t\tBasePath:         managementBasePath,\n\t\tResourceBasePath: resourcePluginBasePath + \"/\" + record.id,\n\t})\n}\n\nfunc normalizeManagementRoute(item pluginapi.ManagementRoute) (string, string, bool) {\n\tif item.Handler == nil {\n\t\treturn \"\", \"\", false\n\t}\n\tmethod := strings.ToUpper(strings.TrimSpace(item.Method))\n\tif method == \"\" {\n\t\tmethod = http.MethodGet\n\t}\n\tif strings.ContainsAny(method, \" \\t\\r\\n\") {","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginhost/management.go#L89-L125","documentation":"The host calls plugin.RegisterManagement during plugin registration inside a deferred recover(). If the plugin's registrar code panics, the host catches it, fuses the plugin (isPluginFused will short-circuit all future calls for its lifetime), and returns this error instead of crashing the process. This is a plugin bug caught by the host's isolation layer.","triggerScenarios":"A management-capable plugin panicking inside RegisterManagement (nil map write, nil deref, index out of range) while registering its management/resource routes.","commonSituations":"Third-party plugin with untested registration code paths; plugin assuming config fields are populated (e.g. iterating a nil route slice after bad config); plugin receiving an unexpected BasePath and panicking.","solutions":["Report/fix the panic in the plugin: the %v payload is the recovered panic value with stack context in plugin logs","Until fixed, disable the plugin in config so registration never runs","If you author the plugin, add defensive nil checks in RegisterManagement and register a recover() of your own","After fixing, reload/restart so the fused plugin becomes callable again"],"exampleFix":"// before (plugin code)\nfunc (p *Plugin) RegisterManagement(ctx context.Context, req pluginapi.ManagementRegistrationRequest) (pluginapi.ManagementRegistrationResponse, error) {\n    p.routes[\"/x\"] = route // panics if routes is nil map\n    ...\n}\n\n// after\nfunc (p *Plugin) RegisterManagement(ctx context.Context, req pluginapi.ManagementRegistrationRequest) (pluginapi.ManagementRegistrationResponse, error) {\n    if p.routes == nil {\n        p.routes = map[string]pluginapi.ManagementRoute{}\n    }\n    p.routes[\"/x\"] = route\n    ...\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"resp, err := h.callManagementRegistrar(ctx, record, plugin)\nif err != nil {\n    // plugin is now fused; registration for it will no-op\n    log.WithError(err).WithField(\"plugin\", record.id).Error(\"management registration failed; plugin disabled\")\n}","preventionTips":["In plugin code, add defer/recover inside RegisterManagement and validate inputs","Initialize maps and slices before writing/iterating them during registration","Load-test plugins in a staging host before enabling in production"],"tags":["plugin","panic","management-api","isolation"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}