router-for-me/CLIProxyAPI · error
plugin executor %s stream panic: %v
Error message
plugin executor %s stream panic: %v
What it means
A panic inside the plugin's ExecuteStream implementation was caught by the executor adapter's deferred recover(). The host converts the panic into a normal Go error, nulls the stream result, and trips the plugin's fuse (circuit breaker) via fusePlugin, so subsequent calls to this plugin fail fast with 'plugin executor ... is unavailable' until the fuse is cleared.
Source
Thrown at internal/pluginhost/adapters_executors.go:670
if errExecute != nil {
return coreexecutor.Response{}, errExecute
}
return coreexecutor.Response{
Payload: a.translateExecutorResponse(ctx, prepared, pluginResp.Payload, false, nil),
Metadata: cloneAnyMap(pluginResp.Metadata),
Headers: cloneHeader(pluginResp.Headers),
}, nil
}
func (a *executorAdapter) ExecuteStream(ctx context.Context, auth *coreauth.Auth, req coreexecutor.Request, opts coreexecutor.Options) (result *coreexecutor.StreamResult, err error) {
if a == nil || a.executor == nil || a.host.isPluginFused(a.pluginID) || !a.host.pluginIdentityCurrent(a.pluginID, a.path, a.version) {
return nil, fmt.Errorf("plugin executor %s is unavailable", a.Identifier())
}
defer func() {
if recovered := recover(); recovered != nil {
a.host.fusePlugin(a.pluginID, "Executor.ExecuteStream", recovered)
result = nil
err = fmt.Errorf("plugin executor %s stream panic: %v", a.Identifier(), recovered)
}
}()
prepared, errPrepare := a.prepareExecutorCall(req, opts)
if errPrepare != nil {
return nil, errPrepare
}
pluginResp, errExecuteStream := a.executor.ExecuteStream(ctx, buildExecutorRequest(a.host, a.provider, auth, prepared.req, prepared.opts))
if errExecuteStream != nil {
return nil, errExecuteStream
}
return &coreexecutor.StreamResult{
Headers: cloneHeader(pluginResp.Headers),
Chunks: mapExecutorStreamChunks(ctx, a.translateExecutorStreamChunks(ctx, prepared, pluginResp.Chunks)),
}, nil
}
func (a *executorAdapter) Refresh(ctx context.Context, auth *coreauth.Auth) (refreshed *coreauth.Auth, err error) {View on GitHub (pinned to 78f0c4079e)
Solutions
- Check the host logs for the panic value and stack captured before the fuse tripped; reproduce the plugin panic by running the plugin standalone
- Fix the panic inside the plugin's ExecuteStream implementation (the %v in the message is the recovered panic value)
- Rebuild/reinstall the plugin so the host picks up the fixed binary; reload plugins or restart the proxy to clear the fuse
- If the plugin is from a vendor, report the panic value and upgrade to a fixed plugin release
Defensive patterns
Strategy: try-catch
Try / catch
// Go: the adapter already recovers; guard the error path.
stream, err := adapter.ExecuteStream(ctx, auth, req, opts)
if err != nil {
if strings.Contains(err.Error(), "stream panic") {
// plugin is now fused; stop retrying and fail over
log.Errorf("plugin stream panic (fused): %v", err)
return failoverOrError(err)
}
return err
} Prevention
- Keep plugins pinned to versions tested against the host's plugin API
- Stream a canary request after plugin install to catch panics before production traffic
- Monitor host logs for fusePlugin events and alert on them
When it happens
Trigger: Calling ExecuteStream on an executorAdapter whose backing plugin (out-of-process or in-process plugin executor) panics during streaming execution — e.g. nil map write, index out of range, or nil pointer dereference inside the plugin's streaming code path.
Common situations: Third-party or custom plugin written in Go that has a bug in its stream handler; plugin built against an older plugin API version whose stream request shape changed; plugin receiving an unexpected model/payload and dereferencing a nil field.
Related errors
- plugin executor %s count tokens panic: %v
- plugin executor %s http request panic: %v
- plugin executor %s refresh panic: %v
- auth provider panic: %v
- plugin executor %s is unavailable
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/9a6fe1923bed2e1c.
Report an issue: GitHub.