router-for-me/CLIProxyAPI · error
plugin sync response is nil
Error message
plugin sync response is nil
What it means
PluginSyncResponse.Validate was invoked on a nil *PluginSyncResponse. Validate is a pointer method that dereferences fields, so it guards against nil receivers first. In practice this indicates a bug in the caller — the response object was never populated (e.g. a failed fetch returned nil and the error was ignored) before validation.
Source
Thrown at internal/pluginstore/home_sync.go:49
func (i *PluginSyncItem) Clear() {
if i == nil {
return
}
ClearResolvedAuthConfigs(i.Auth)
i.Auth = nil
i.Manifest = Manifest{}
}
type PluginSyncResponse struct {
SchemaVersion int `json:"schema_version"`
ExpiresAt time.Time `json:"expires_at"`
Items []PluginSyncItem `json:"items"`
}
func (r *PluginSyncResponse) Validate(now time.Time) error {
if r == nil {
return fmt.Errorf("plugin sync response is nil")
}
if r.SchemaVersion != PluginSyncSchemaVersion {
return fmt.Errorf("unsupported plugin sync schema_version %d", r.SchemaVersion)
}
if r.ExpiresAt.IsZero() {
return fmt.Errorf("plugin sync response missing expires_at")
}
if !now.Before(r.ExpiresAt) {
return fmt.Errorf("plugin sync response expired")
}
seen := make(map[string]struct{}, len(r.Items))
for index := range r.Items {
item := &r.Items[index]
if errManifest := item.Manifest.Validate(); errManifest != nil {
return fmt.Errorf("plugin sync item %d: %w", index, errManifest)
}
if errURLs := validatePluginSyncManifestURLs(item.Manifest); errURLs != nil {
return fmt.Errorf("plugin sync item %d: %w", index, errURLs)View on GitHub (pinned to 78f0c4079e)
Solutions
- Check the error returned by the sync-fetch call before calling Validate
- Ensure the response variable is assigned from a successful fetch in every code path
- Add a nil check on the response pointer at the call site for defensive clarity
Example fix
// before
resp, _ := fetchSync(ctx)
err := resp.Validate(time.Now()) // panic risk / nil error
// after
resp, err := fetchSync(ctx)
if err != nil {
return err
}
if err := resp.Validate(time.Now()); err != nil {
return err
} Defensive patterns
Strategy: validation
Validate before calling
if resp == nil {
return errors.New("sync response is nil; fetch failed or was skipped")
} Type guard
func hasSyncResponse(r *pluginstore.PluginSyncResponse) bool { return r != nil } Try / catch
if err := resp.Validate(now); err != nil && strings.Contains(err.Error(), "is nil") {
// fix the fetch path that returned nil without propagating its error
} Prevention
- Always handle the fetch error before using the response
- Return early on fetch failures instead of falling through to validation
- Lint for unchecked error returns on functions returning (ptr, error)
When it happens
Trigger: Calling var r *PluginSyncResponse; r.Validate(now) or passing the result of a sync fetch whose error was ignored, leaving the pointer nil.
Common situations: Ignoring the error from the sync-fetch call and proceeding to Validate; early-return paths that skip assignment; refactor moving validation before population.
Related errors
- ExecuteModel requires Stream=false
- ExecuteModelStream requires Stream=true
- ExecuteProtocolWithAuthManager requires Stream=false
- ExecuteProtocolStreamWithAuthManager requires Stream=true
- weight must not exceed %d
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/cd74d778c6f2f635.
Report an issue: GitHub.