router-for-me/CLIProxyAPI · error

plugin executor %s not found

Error message

plugin executor %s not found

What it means

executorAdapterForPlugin iterated all active plugin records and none matched the requested pluginID. The plugin is either not loaded, disabled, or its registered id differs (case/whitespace) from what the router passed.

Source

Thrown at internal/pluginhost/executor_route.go:138

	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

  1. List active plugins (host logs at startup, or management API) and compare ids with the routing config value.
  2. Fix the id in the model-to-plugin mapping to match the plugin's registered id exactly.
  3. If the plugin failed to load, resolve the load error first (missing dependency, bad manifest, wrong architecture).

Example fix

# before (config.yaml)
models:
  - name: "my-model"
    plugin: "MyExecutor-Plugin"   # wrong case

# after
models:
  - name: "my-model"
    plugin: "my-executor-plugin" # exact registered id
Defensive patterns

Strategy: validation

Validate before calling

known := map[string]bool{}
for _, rec := range host.ActiveRecords() {
    known[rec.ID] = true
}
if !known[pluginID] {
    return fmt.Errorf("plugin %q not loaded; active plugins: %v", pluginID, keys(known))
}

Type guard

func pluginLoaded(h *pluginhost.Host, id string) bool {
    for _, rec := range h.ActiveRecords() {
        if rec.ID == id {
            return true
        }
    }
    return false
}

Try / catch

adapter, err := host.ExecutorAdapterForPlugin(pluginID)
if err != nil && strings.Contains(err.Error(), "not found") {
    return configErrorf("unknown plugin %q in model routing; check installed plugins", pluginID)
}

Prevention

When it happens

Trigger: Routing a model to a plugin id that is not among activeRecords(): plugin not installed, failed to load at startup, excluded by config, or an id mismatch such as trailing characters or wrong case.

Common situations: Config references a plugin that was removed from the plugins directory; plugin file failed to load (check startup logs for load errors) so it never became active; id typo in model routing.

Related errors


AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15). Data as JSON: /api/errors/1ca3883b368b6a19. Report an issue: GitHub.