router-for-me/CLIProxyAPI · error
direct install plugin %q not found in source
Error message
direct install plugin %q not found in source
What it means
Returned during direct-install resolution when the registry was fetched successfully from the source URL but registry.PluginByID(manifest.ID) finds no entry with that ID. The manifest references a plugin the source registry does not know about. The library treats this as a hard mismatch because it cannot construct artifact coordinates for an unknown plugin.
Source
Thrown at internal/pluginstore/install.go:203
if len(plugin.Install.Artifacts) > 0 {
return plugin, nil
}
sourceURL := strings.TrimSpace(manifest.SourceURL)
if sourceURL == "" {
sourceURL = strings.TrimSpace(c.RegistryURL)
}
if sourceURL == "" {
return Plugin{}, fmt.Errorf("direct install manifest missing source-url")
}
sourceClient := c
sourceClient.RegistryURL = sourceURL
registry, errRegistry := sourceClient.FetchRegistry(ctx)
if errRegistry != nil {
return Plugin{}, fmt.Errorf("fetch direct install source: %w", errRegistry)
}
resolved, okPlugin := registry.PluginByID(manifest.ID)
if !okPlugin {
return Plugin{}, fmt.Errorf("direct install plugin %q not found in source", strings.TrimSpace(manifest.ID))
}
if PluginInstallType(resolved) != InstallTypeDirect {
return Plugin{}, fmt.Errorf("direct install plugin %q resolved as %q", strings.TrimSpace(manifest.ID), PluginInstallType(resolved))
}
return directPluginVersion(resolved, manifest.ID, manifest.Version)
}
func directPluginVersion(plugin Plugin, id string, version string) (Plugin, error) {
id = strings.TrimSpace(id)
version = normalizeVersion(version)
if normalizeVersion(plugin.Version) == version {
plugin.Version = version
plugin.Install = NormalizeInstallPlan(plugin.Install)
plugin.Install.Type = InstallTypeDirect
if errPlan := ValidateInstallPlan(plugin.Install); errPlan != nil {
return Plugin{}, fmt.Errorf("direct install plugin %q version %q: %w", id, version, errPlan)
}
return plugin, nilView on GitHub (pinned to 78f0c4079e)
Solutions
- Fetch the registry document and confirm the exact plugin ID exists (compare case and spelling verbatim)
- Update manifest.ID to the current ID published by the source registry
- Point manifest.SourceURL at the registry that actually hosts the plugin
Example fix
// before manifest.ID = "example-plugin " // trailing space or wrong name // after manifest.ID = "example-plugin" // exact ID as published in the source registry plugin, err := client.ResolveDirect(ctx, manifest)
Defensive patterns
Strategy: validation
Validate before calling
func pluginExistsInRegistry(ctx context.Context, c pluginstore.Client, id string) (bool, error) {
reg, err := c.FetchRegistry(ctx)
if err != nil {
return false, err
}
_, ok := reg.PluginByID(strings.TrimSpace(id))
return ok, nil
} Type guard
func isPluginNotFoundInSource(err error) bool {
return err != nil && strings.Contains(err.Error(), "not found in source")
} Try / catch
if err := client.ResolveDirect(ctx, manifest); err != nil {
if isPluginNotFoundInSource(err) {
// surface actionable message: list available IDs from FetchRegistry
}
} Prevention
- Validate manifest IDs against the registry before distributing manifests
- Trim and canonicalize IDs (case, whitespace) at authoring time
- Subscribe to registry change notices so renames/removals are caught early
When it happens
Trigger: manifest.ID is trimmed and looked up in the source registry; mismatch happens when the plugin was renamed, removed from the registry, the manifest was written against a different registry, or the ID has a typo/case difference.
Common situations: Plugin renamed upstream but local manifests still use the old ID; pointing SourceURL at the wrong registry (staging vs production); trailing whitespace or case differences in the ID; plugin deprecated and pruned from the registry; typo in a hand-edited manifest.
Related errors
- fetch direct install source: %w
- direct install plugin %q resolved as %q
- direct install plugin %q version %q not found in source
- direct install manifest missing source-url
- direct install plugin %q version %q: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/fc7b3ea03c8677e7.
Report an issue: GitHub.