router-for-me/CLIProxyAPI · error
plugin %s does not declare an executor
Error message
plugin %s does not declare an executor
What it means
The plugin with the given ID is active but its manifest/capability set has no Executor capability (record.plugin.Capabilities.Executor == nil). The host was asked to build an executor adapter for a plugin that simply does not provide model execution.
Source
Thrown at internal/pluginhost/executor_route.go:129
func (h *Host) executorAdapterForPlugin(pluginID string) (*executorAdapter, error) {
if h == nil {
return nil, fmt.Errorf("plugin host is unavailable")
}
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
- Verify the plugin's manifest declares an executor capability and that its id matches the routing config exactly.
- Correct the model-to-plugin mapping in config to point at the plugin that actually provides the executor.
- Update/reinstall the plugin to a version that declares Executor.
Example fix
# before (config.yaml)
models:
- name: "my-model"
plugin: "my-auth-plugin" # no executor capability
# after
models:
- name: "my-model"
plugin: "my-executor-plugin" # declares Executor Defensive patterns
Strategy: validation
Validate before calling
for _, rec := range host.ActiveRecords() {
if rec.ID == wantedPluginID && rec.Plugin.Capabilities.Executor != nil {
return nil // routing target is valid
}
}
return fmt.Errorf("plugin %s has no executor capability", wantedPluginID) Type guard
func pluginDeclaresExecutor(rec pluginRecord) bool {
return rec.Plugin.Capabilities.Executor != nil
} Try / catch
adapter, err := host.ExecutorAdapterForPlugin(pluginID)
if err != nil && strings.Contains(err.Error(), "does not declare an executor") {
return configErrorf("model %s routed to non-executor plugin %s; fix models config", model, pluginID)
} Prevention
- Validate model-routing config against installed plugin capabilities at startup.
- Keep a catalog of which installed plugins provide executors versus auth-only.
When it happens
Trigger: Routing execution to a plugin that only provides auth, command-line, or router capabilities; typo in the plugin id in model routing config that happens to match a non-executor plugin; plugin version that dropped or renamed the executor capability.
Common situations: Config lists the wrong plugin id for a model; plugin downgrade where executor support was removed; a manifest parsing issue silently dropping the Executor capability.
Related errors
- target executor plugin id is required
- plugin executor %s has no provider identifier
- plugin executor %s not found
- plugin host is unavailable
- plugin executor %s is unavailable
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/3e2b689da2c82427.
Report an issue: GitHub.