router-for-me/CLIProxyAPI · error
auth provider start login panic: %v
Error message
auth provider start login panic: %v
What it means
This error is produced by the plugin host's panic guard around a plugin's AuthProvider.StartLogin capability. When a loaded plugin's StartLogin method panics (instead of returning an error), the host recovers the panic, 'fuses' the plugin (marks it as failed after repeated panics), and returns this error to the caller. It means the crash happened inside third-party plugin code, not in the host itself.
Source
Thrown at internal/pluginhost/auth_provider.go:276
func (h *Host) StartLogin(ctx context.Context, provider string, baseURL string) (pluginapi.AuthLoginStartResponse, bool, error) {
record := h.authProviderRecord(provider)
if record == nil {
return pluginapi.AuthLoginStartResponse{}, false, nil
}
return h.callStartLogin(ctx, *record, provider, baseURL)
}
func (h *Host) callStartLogin(ctx context.Context, record capabilityRecord, provider string, baseURL string) (resp pluginapi.AuthLoginStartResponse, handled bool, err error) {
authProvider := record.plugin.Capabilities.AuthProvider
if h == nil || authProvider == nil || h.isPluginFused(record.id) || !h.recordCurrent(record) {
return pluginapi.AuthLoginStartResponse{}, false, nil
}
defer func() {
if recovered := recover(); recovered != nil {
h.fusePlugin(record.id, "AuthProvider.StartLogin", recovered)
resp = pluginapi.AuthLoginStartResponse{}
handled = false
err = fmt.Errorf("auth provider start login panic: %v", recovered)
}
}()
req := pluginapi.AuthLoginStartRequest{
Provider: normalizeProviderID(provider),
BaseURL: strings.TrimSpace(baseURL),
Host: h.hostConfigSummary(),
HTTPClient: h.newHTTPClient(nil),
}
resp, errStart := authProvider.StartLogin(ctx, req)
if errStart != nil {
return pluginapi.AuthLoginStartResponse{}, true, errStart
}
return resp, true, nil
}
func (h *Host) PollLogin(ctx context.Context, provider, state string, metadata ...map[string]any) (pluginapi.AuthLoginPollResponse, bool, error) {
record := h.authProviderRecord(provider)
if record == nil {View on GitHub (pinned to 78f0c4079e)
Solutions
- Check the plugin identity in the fused-plugin log line (fusePlugin records the capability 'AuthProvider.StartLogin' and the recovered value) to identify which plugin panicked.
- Reproduce outside the host: run the plugin's StartLogin directly with the same Provider/BaseURL inputs to get a real stack trace.
- Update or replace the plugin with a version that returns errors instead of panicking; report the panic plus recovered value to the plugin author.
- If you own the plugin, audit StartLogin for nil map dereferences, unguarded type assertions, and missing-value assumptions; add defensive checks and return errors.
- Restart or reload the host to reset the fuse if the panic was a one-off (e.g. transient nil HTTPClient).
Example fix
// plugin side, before (panics on nil metadata)
func (p *Provider) StartLogin(ctx context.Context, req pluginapi.AuthLoginStartRequest) (pluginapi.AuthLoginStartResponse, error) {
url := req.Metadata["redirect"] // panics if Metadata is nil
...
}
// after
func (p *Provider) StartLogin(ctx context.Context, req pluginapi.AuthLoginStartRequest) (pluginapi.AuthLoginStartResponse, error) {
if req.Metadata == nil {
return pluginapi.AuthLoginStartResponse{}, fmt.Errorf("start login: metadata is required")
}
url, ok := req.Metadata["redirect"]
if !ok {
return pluginapi.AuthLoginStartResponse{}, fmt.Errorf("start login: redirect missing")
}
...
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before starting login, confirm the provider is plugin-backed and not fused
if !host.ProviderHasActiveAuthPlugin(providerID) {
return fmt.Errorf("provider %s has no healthy auth plugin; run built-in flow", providerID)
} Type guard
func isHealthyAuthProvider(h *pluginhost.Host, provider string) bool {
if h == nil {
return false
}
rec := h.AuthProviderRecord(provider)
return rec != nil && rec.Plugin.Capabilities.AuthProvider != nil && !h.IsPluginFused(rec.ID)
} Try / catch
resp, handled, err := host.CallStartLogin(ctx, provider, baseURL)
if err != nil {
if strings.Contains(err.Error(), "start login panic") {
log.WithError(err).Error("auth plugin panicked during start login; falling back to built-in flow")
// plugin is now fused; use non-plugin path or surface actionable error to user
}
return err
}
if !handled {
// no plugin claimed this provider; use built-in auth flow
} Prevention
- Pin plugin versions tested against your host version.
- Prefer plugins that return errors instead of panicking; check their changelog for panic fixes.
- Watch fuse logs so a repeatedly panicking plugin is removed before it degrades login flows.
When it happens
Trigger: Calling the login-start flow for a provider backed by a plugin (e.g. a management/API endpoint that triggers login) whose StartLogin implementation panics: nil map writes, nil pointer dereferences, index out of range, or missing metadata the plugin expected in the AuthLoginStartRequest (Provider, BaseURL, Host, HTTPClient).
Common situations: Installing a buggy or version-mismatched auth plugin; plugin assumes fields the host left empty; plugin written against an older pluginapi AuthLoginStartRequest shape; plugin panics when BaseURL is empty because the caller passed no --base-url.
Related errors
- auth provider poll login panic: %v
- auth provider panic: %v
- auth provider refresh panic: %v
- plugin executor %s refresh panic: %v
- auth provider %s returned auth without provider
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/6c01de09932625d1.
Report an issue: GitHub.