{"record":{"id":"3214e326fe072452","repo":"OpenNHP/opennhp","slug":"plugin-validation-failed","errorCode":null,"errorMessage":"plugin validation failed","messagePattern":"plugin validation failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"endpoints/server/udpserver.go","lineNumber":1138,"sourceCode":"\ts.authServiceMapMutex.Unlock()\n\n\treturn nil\n}\n\nfunc (s *UdpServer) ValidatePlugin(h plugins.PluginHandler) bool {\n\t// placeholder to validate plugin file\n\t// err = checkSignature(s.Signature())\n\t// if err != nil {\n\t//   return false\n\t// }\n\n\treturn true\n}\n\nfunc (s *UdpServer) LoadPlugin(pluginId string, h plugins.PluginHandler) error {\n\tif !s.ValidatePlugin(h) {\n\t\tlog.Error(\"Plugin: %s validation failed\", pluginId)\n\t\treturn fmt.Errorf(\"plugin validation failed\")\n\t}\n\n\ts.pluginHandlerMapMutex.Lock()\n\toldHandler, found := s.pluginHandlerMap[pluginId]\n\ts.pluginHandlerMapMutex.Unlock()\n\tif found {\n\t\toldHandler.Close()\n\t}\n\n\tpluginDirPath := filepath.Join(ExeDirPath, \"plugins\", pluginId)\n\terr := h.Init(&plugins.PluginParamsIn{\n\t\tPluginDirPath: &pluginDirPath,\n\t\tLog:           s.log.NewSubLogger(\"Plugin[\"+pluginId+\"]\", log.LogLevelDebug),\n\t\tHostname:      &s.config.Hostname,\n\t\tLocalIp:       &s.localIp,\n\t\tLocalMac:      &s.localMac,\n\t})\n\tif err != nil {","sourceCodeStart":1120,"sourceCodeEnd":1156,"githubUrl":"https://github.com/OpenNHP/opennhp/blob/6e04ca5ff03222a699c24205cd4bf8fee9af7ffe/endpoints/server/udpserver.go#L1120-L1156","documentation":"LoadPlugin runs UdpServer.ValidatePlugin on the provided plugins.PluginHandler before registering it; a handler missing required methods or returning false from validation is rejected and never added to pluginHandlerMap. This keeps half-implemented plugins from being invoked at request time.","triggerScenarios":"Calling UdpServer.LoadPlugin(pluginId, h) where h is nil or fails ValidatePlugin (e.g. missing required handler methods in a partially built Go plugin).","commonSituations":"Building a custom server plugin that doesn't implement the full PluginHandler interface (AuthWithNHP, AuthWithHttp, RegisterAgent, ListService, etc.); loading a .so compiled against a mismatched plugin API version; registering a nil handler when a plugin file failed to load.","solutions":["Implement every method of the plugins.PluginHandler interface on the handler type","Rebuild the plugin .so against the same opennhp version/interface as the running serverd","Pass a non-nil handler; check the plugin load step for errors before LoadPlugin","Compare the handler against examples/server_plugin for the expected method set"],"exampleFix":"// before\ntype myPlugin struct{} // missing AuthWithHttp\nfunc (p *myPlugin) AuthWithNHP(...) {...}\n// after — implement the full interface\ntype myPlugin struct{}\nfunc (p *myPlugin) AuthWithNHP(...) {...}\nfunc (p *myPlugin) AuthWithHttp(...) {...}\nfunc (p *myPlugin) RegisterAgent(...) {...}\nfunc (p *myPlugin) ListService(...) {...}","handlingStrategy":"type-guard","validationCode":"var _ plugins.PluginHandler = (*MyPlugin)(nil) // compile-time interface check before LoadPlugin\nif h == nil { return errors.New(\"plugin handler is nil\") }\nerr := srv.LoadPlugin(pluginId, h)","typeGuard":"func implementsPluginHandler(h plugins.PluginHandler) bool { return h != nil }","tryCatchPattern":"if err := srv.LoadPlugin(id, h); err != nil {\n    if strings.Contains(err.Error(), \"validation failed\") {\n        log.Errorf(\"plugin %s does not implement PluginHandler fully: %v\", id, err)\n    }\n    return err\n}","preventionTips":["Add a compile-time assertion `var _ plugins.PluginHandler = (*T)(nil)` to every plugin","Build plugins from the same commit/tag as the running serverd","Test plugin loading in CI before deploying"],"tags":["plugin","validation","interface"],"backgroundTag":"schema-validation-failed","analyzedSha":"6e04ca5ff03222a699c24205cd4bf8fee9af7ffe","analyzedAt":"2026-09-07T15:44:59.941Z","contentChangedAt":"2026-09-07T15:44:59.941Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}