router-for-me/CLIProxyAPI · error
plugin executor %s has no provider identifier
Error message
plugin executor %s has no provider identifier
What it means
The plugin declares an Executor capability, but h.executorProvider cannot derive a provider identifier for it (okProvider == false). Without a provider identifier the host cannot register the executor into its provider registry, so routing fails with this error.
Source
Thrown at internal/pluginhost/executor_route.go:133
}
pluginID = strings.TrimSpace(pluginID)
if pluginID == "" {
return nil, fmt.Errorf("target executor plugin id is required")
}
for _, record := range h.activeRecords() {
if record.id != pluginID {
continue
}
if h.isPluginFused(record.id) {
return nil, fmt.Errorf("plugin executor %s is unavailable", pluginID)
}
executor := record.plugin.Capabilities.Executor
if executor == nil {
return nil, fmt.Errorf("plugin %s does not declare an executor", pluginID)
}
provider, okProvider := h.executorProvider(record, executor)
if !okProvider {
return nil, fmt.Errorf("plugin executor %s has no provider identifier", pluginID)
}
registration := newExecutorAdapterRegistration(h, record, provider, executor)
return registration.adapter, nil
}
return nil, fmt.Errorf("plugin executor %s not found", pluginID)
}
View on GitHub (pinned to 78f0c4079e)
Solutions
- Check the plugin's executor implementation: the provider identifier (as expected by the host's executorProvider) must return a non-empty value.
- Rebuild the plugin against the same pluginapi version as the host.
- If a third-party plugin, report to its maintainer that the executor capability lacks a provider identifier.
Example fix
// plugin side, before
func (e *Executor) Provider() string { return "" }
// after
func (e *Executor) Provider() string { return "my-provider" } Defensive patterns
Strategy: validation
Validate before calling
// Plugin-side self-check before returning the capability
if strings.TrimSpace(myProviderID) == "" {
panic("executor capability configured without provider identifier") // fail at plugin load, not per request
} Type guard
func executorHasProvider(h *pluginhost.Host, rec pluginRecord) bool {
_, ok := h.ExecutorProvider(rec, rec.Plugin.Capabilities.Executor)
return ok
} Try / catch
adapter, err := host.ExecutorAdapterForPlugin(pluginID)
if err != nil && strings.Contains(err.Error(), "no provider identifier") {
// plugin defect: permanent; disable routing to it and file an issue
return disableRouteAndReport(pluginID, err)
} Prevention
- Pin plugin builds to the host's pluginapi version.
- Add a load-time contract test: every executor capability must expose a non-empty provider id.
When it happens
Trigger: An executor capability whose metadata omits or leaves blank the provider identifier field the host reads (e.g. Provider()/provider metadata method returning ""). The plugin structurally looks like an executor but is not identifiable.
Common situations: Plugin built against a newer or older pluginapi where the provider identifier accessor changed; a plugin that implements the Executor interface partially, leaving the identifier method's zero value; manifest field renamed between versions.
Related errors
- target executor plugin id is required
- plugin %s does not declare an executor
- auth provider %s returned auth without provider
- auth provider %s returned invalid auth data
- auth provider refresh returned invalid auth data
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/bec5ceba7a1be246.
Report an issue: GitHub.