router-for-me/CLIProxyAPI · error

plugin sync item %d: %w

Error message

plugin sync item %d: %w

What it means

While validating each item in the sync response, item.Manifest.Validate() failed and the error is wrapped with the item's index ('plugin sync item N: ...'). The underlying message names the actual manifest defect (bad/missing ID, name, version, and so on). This variant specifically points at manifest-structure problems as opposed to URL policy (error 629).

Source

Thrown at internal/pluginstore/home_sync.go:64

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)
		}
		id := strings.TrimSpace(item.Manifest.ID)
		if _, exists := seen[id]; exists {
			return fmt.Errorf("plugin sync response contains duplicate plugin %q", id)
		}
		seen[id] = struct{}{}
		for authIndex := range item.Auth {
			if errAuth := ValidateResolvedAuthConfig(item.Auth[authIndex]); errAuth != nil {
				return fmt.Errorf("plugin sync item %d auth %d: %w", index, authIndex, errAuth)
			}
		}
	}
	return nil
}

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Read the wrapped error text — it names the exact manifest field problem
  2. Fix the manifest at index N in the sync index (server side) or remove the entry
  3. Upgrade the client if the manifest uses a newer legitimate format
  4. Re-fetch the index; transient serving of a broken file resolves on refresh
Defensive patterns

Strategy: validation

Validate before calling

for i := range resp.Items {
    if err := resp.Items[i].Manifest.Validate(); err != nil {
        return fmt.Errorf("pre-check item %d manifest: %w", i, err)
    }
}

Try / catch

var idxErr error
if err != nil && strings.Contains(err.Error(), "plugin sync item") {
    // parse index from message; fix/drop that entry server-side, or skip that plugin locally
}

Prevention

When it happens

Trigger: Validate on a sync response where item N's manifest fails its own Validate — missing required fields, malformed ID/version strings, invalid install block.

Common situations: Plugin index entry edited by hand with a missing id or version; a plugin author pushing a manifest the client's stricter validation rejects after an upgrade.

Related errors


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