m1k1o/neko · error
plugin '%s' not found
Error message
plugin '%s' not found
What it means
Returned by Manager.LookupService when no registered plugin matches pluginName (findPlugin on the dependency registry fails). LookupService exposes an exposable plugin's service; the lookup is purely by the name returned by plugin.Name().
Source
Thrown at server/internal/plugins/manager.go:151
} else {
manager.logger.Err(err).Msg("failed to start plugins, skipping...")
}
}
}
func (manager *ManagerCtx) Shutdown() error {
_ = manager.plugins.forEach(func(d *dependency) error {
err := d.plugin.Shutdown()
manager.logger.Err(err).Str("plugin", d.plugin.Name()).Msg("plugin shutdown")
return nil
})
return nil
}
func (manager *ManagerCtx) LookupService(pluginName string) (any, error) {
plug, ok := manager.plugins.findPlugin(pluginName)
if !ok {
return nil, fmt.Errorf("plugin '%s' not found", pluginName)
}
expPlug, ok := plug.plugin.(types.ExposablePlugin)
if !ok {
return nil, fmt.Errorf("plugin '%s' is not exposable", pluginName)
}
return expPlug.ExposeService(), nil
}
func (manager *ManagerCtx) Metadata() []types.PluginMetadata {
var plugins []types.PluginMetadata
_ = manager.plugins.forEach(func(d *dependency) error {
dependsOn := make([]string, 0)
deps, isDependalbe := d.plugin.(types.DependablePlugin)
if isDependalbe {
dependsOn = deps.DependsOn()View on GitHub (pinned to b0f01cedea)
Solutions
- Verify the exact plugin name (the value of plugin.Name()) and fix the LookupService argument
- Check startup logs for plugin load errors — if the plugin failed to load it will not be in the registry
- Ensure plugins are loaded and InitConfigs/Start completed before LookupService is called
- Guard the call site: treat the error as expected for optional plugins and fall back gracefully
Example fix
// before
svc, err := manager.LookupService("file_tranfer") // typo
// after
svc, err := manager.LookupService("filetransfer")
if err != nil {
log.Warn().Err(err).Str("plugin", name).Msg("plugin service unavailable")
return
} Defensive patterns
Strategy: fallback
Validate before calling
// ensure plugin load phase completed and name exists before lookup
if len(manager.Plugins()) == 0 {
return fmt.Errorf("plugins not loaded yet")
}
if _, ok := manager.plugins.findPlugin(name); !ok {
return fmt.Errorf("unknown plugin %q; known: %v", name, knownNames())
} Try / catch
svc, err := manager.LookupService(name)
if err != nil {
if strings.Contains(err.Error(), "not found") {
// optional plugin: degrade gracefully
return nil, nil
}
return nil, err
} Prevention
- Copy plugin names from plugin.Name() / a shared constant, never by hand
- Gate service lookups behind plugin startup readiness
- Log the list of registered plugin names at startup to make typos obvious
When it happens
Trigger: Calling LookupService(name) where name was never registered — typo in the name, the plugin failed to load/start earlier, or the plugin was removed (e.g. its deps entry deleted by the cycle-break in addPlugin).
Common situations: Typo'd plugin name in handler wiring; a plugin whose load failed at startup (see errors 67/68) so it never entered the registry; requesting a service before plugin load/init completed.
Related errors
- member does not exist
- session not found
- webrtc data channel not found
- webrtc connection not found
- webrtc stream not found
AI-assisted analysis of m1k1o/neko@b0f01cedea (2026-09-01).
Data as JSON: /api/errors/2e817618aa360b02.
Report an issue: GitHub.