{"record":{"id":"14a3a971d0de2def","repo":"gotify/server","slug":"unknown-plugin-version-unrecogninzed-getgotifyplu","errorCode":null,"errorMessage":"unknown plugin version (unrecogninzed GetGotifyPluginInfo signature %T)","messagePattern":"unknown plugin version \\(unrecogninzed GetGotifyPluginInfo signature %T\\)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"plugin/compat/wrap.go","lineNumber":33,"sourceCode":"\t\treturn nil, errors.New(\"missing GetGotifyPluginInfo symbol\")\n\t}\n\tswitch getInfoHandle := getInfoHandle.(type) {\n\tcase func() papiv1.Info:\n\t\tv1 := PluginV1{}\n\n\t\tv1.Info = getInfoHandle()\n\t\tnewInstanceHandle, err := p.Lookup(\"NewGotifyPluginInstance\")\n\t\tif err != nil {\n\t\t\treturn nil, errors.New(\"missing NewGotifyPluginInstance symbol\")\n\t\t}\n\t\tconstructor, ok := newInstanceHandle.(func(ctx papiv1.UserContext) papiv1.Plugin)\n\t\tif !ok {\n\t\t\treturn nil, fmt.Errorf(\"NewGotifyPluginInstance signature mismatch, func(ctx plugin.UserContext) plugin.Plugin expected, got %T\", newInstanceHandle)\n\t\t}\n\t\tv1.Constructor = constructor\n\t\treturn v1, nil\n\tdefault:\n\t\treturn nil, fmt.Errorf(\"unknown plugin version (unrecogninzed GetGotifyPluginInfo signature %T)\", getInfoHandle)\n\t}\n}\n","sourceCodeStart":15,"sourceCodeEnd":36,"githubUrl":"https://github.com/gotify/server/blob/14bfc256276775c425f988d621dccfe705de18ac/plugin/compat/wrap.go#L15-L36","documentation":"Wrap switches on the concrete type of the plugin's GetGotifyPluginInfo symbol to detect the plugin API version. If the symbol's type matches none of the known version signatures, the plugin version is unknown and this error (note the 'unrecogninzed' typo) is returned.","triggerScenarios":"A plugin exports a GetGotifyPluginInfo function whose signature does not match any supported version's expected type, or the symbol is of an unexpected type entirely (e.g. a variable, not a function).","commonSituations":"Loading a plugin built for a much newer or older plugin-api major version, or loading a non-plugin shared library that happens to export GetGotifyPluginInfo.","solutions":["Rebuild the plugin against a supported plugin-api version","Verify GetGotifyPluginInfo is declared with one of the supported signatures (e.g. func() (int, plugin.PluginInfo))","Check the plugin's go.mod pins a compatible version of the gotify plugin-api","Confirm you are loading a real Gotify plugin, not an arbitrary shared object"],"exampleFix":"// before (unsupported newer API)\nfunc GetGotifyPluginInfo() (int, plugin.PluginInfo, extra.Metadata) { ... }\n// after (supported v1)\nfunc GetGotifyPluginInfo() (int, plugin.PluginInfo) { return 1, plugin.PluginInfo{...} }","handlingStrategy":"type-guard","validationCode":"sym, err := p.Lookup(\"GetGotifyPluginInfo\")\nif err != nil { panic(\"missing symbol\") }\nswitch sym.(type) {\ncase func() (int, papiv1.PluginInfo):\n    // supported v1\ndefault:\n    fmt.Printf(\"unsupported version signature: %T\\n\", sym)\n}","typeGuard":"func isSupportedInfoSignature(h interface{}) bool {\n    switch h.(type) {\n    case func() (int, papiv1.PluginInfo):\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"compat, err := wrapper.Wrap(pluginPath)\nif err != nil {\n    if strings.Contains(err.Error(), \"unknown plugin version\") {\n        log.Printf(\"unsupported plugin %s: %v\", pluginPath, err)\n        return nil\n    }\n    return err\n}","preventionTips":["Build plugins only against supported plugin-api major versions","Verify GetGotifyPluginInfo signature before distributing a plugin","Test-load every plugin in CI before release"],"tags":["plugin","versioning","compatibility"],"backgroundTag":"plugin-version-unsupported","analyzedSha":"14bfc256276775c425f988d621dccfe705de18ac","analyzedAt":"2026-09-05T12:52:36.781Z","contentChangedAt":"2026-09-05T12:52:36.781Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}