router-for-me/CLIProxyAPI · error

auth provider panic: %v

Error message

auth provider panic: %v

What it means

Constructed in Host.callParseAuths' recover() handler when the plugin's AuthProvider.ParseAuth implementation panics. The host trips the plugin's fuse (fusePlugin) so the misbehaving plugin is skipped in subsequent calls, and returns this error describing the recovered panic value.

Source

Thrown at internal/pluginhost/auth_provider.go:212

func (h *Host) callParseAuth(ctx context.Context, record capabilityRecord, req pluginapi.AuthParseRequest) (auth *coreauth.Auth, handled bool, err error) {
	auths, handled, errParseAuths := h.callParseAuths(ctx, record, req)
	if errParseAuths != nil || !handled || len(auths) == 0 {
		return nil, handled, errParseAuths
	}
	return auths[0], true, nil
}

func (h *Host) callParseAuths(ctx context.Context, record capabilityRecord, req pluginapi.AuthParseRequest) (auths []*coreauth.Auth, handled bool, err error) {
	provider := record.plugin.Capabilities.AuthProvider
	if h == nil || provider == nil || h.isPluginFused(record.id) || !h.recordCurrent(record) {
		return nil, false, nil
	}
	defer func() {
		if recovered := recover(); recovered != nil {
			h.fusePlugin(record.id, "AuthProvider.ParseAuth", recovered)
			auths = nil
			handled = false
			err = fmt.Errorf("auth provider panic: %v", recovered)
		}
	}()
	if req.Host.AuthDir == "" {
		req.Host = h.hostConfigSummary()
	}
	req.Provider = normalizeProviderID(req.Provider)
	if req.Provider == "" {
		req.Provider = normalizeProviderID(provider.Identifier())
	}
	req.RawJSON = bytes.Clone(req.RawJSON)
	resp, errParse := provider.ParseAuth(ctx, req)
	if errParse != nil {
		return nil, false, errParse
	}
	if !resp.Handled {
		return nil, false, nil
	}
	datas := pluginAuthParseResponseAuths(resp)

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Check host logs for the fuse record identifying the plugin id and panic stack
  2. Update or patch the plugin so ParseAuth handles the input defensively and returns errors instead of panicking
  3. After fixing, restart or un-fuse the plugin per the host's fuse policy so it is consulted again
  4. As a workaround, remove/disable the faulty plugin so other providers continue working

Example fix

// before (plugin side)
func (p *Provider) ParseAuth(ctx context.Context, req AuthParseRequest) (*AuthParseResponse, error) {
    return &AuthParseResponse{Auth: AuthData{Provider: req.RawJSON["type"]}}, nil // may panic
}

// after
func (p *Provider) ParseAuth(ctx context.Context, req AuthParseRequest) (*AuthParseResponse, error) {
    t, _ := req.RawJSON["type"].(string)
    if t == "" {
        return nil, fmt.Errorf("auth payload missing type")
    }
    return &AuthParseResponse{Auth: AuthData{Provider: t}}, nil
}
Defensive patterns

Strategy: try-catch

Try / catch

if err != nil && strings.Contains(err.Error(), "auth provider panic") {
    // identify plugin from the message/logs; it is now fused — disable or update it,
    // and let other providers serve the request
}

Prevention

When it happens

Trigger: A plugin's ParseAuth hits a nil dereference, index-out-of-range, or assertion panic while parsing auth data; once fused, the plugin stops being consulted until fuse conditions clear.

Common situations: Third-party plugin bug triggered by unexpected auth payload shapes; plugin built against an older contract passing unexpected types; empty/edge-case RawJSON reaching a plugin that assumes fields exist.

Related errors


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