router-for-me/CLIProxyAPI · error

direct plugin sync manifest requires pinned artifacts

Error message

direct plugin sync manifest requires pinned artifacts

What it means

validatePluginSyncManifestURLs found an install_type=direct manifest whose normalized install plan contains zero artifacts. Direct installs download pinned artifacts, so an empty plan is meaningless and rejected. Non-direct install types bypass this check.

Source

Thrown at internal/pluginstore/home_sync.go:89

			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
}

func validatePluginSyncManifestURLs(manifest Manifest) error {
	if manifest.InstallType() != InstallTypeDirect {
		return nil
	}
	plan := NormalizeInstallPlan(manifest.Install)
	if len(plan.Artifacts) == 0 {
		return fmt.Errorf("direct plugin sync manifest requires pinned artifacts")
	}
	for index, artifact := range plan.Artifacts {
		parsed, errParse := url.Parse(strings.TrimSpace(artifact.URL))
		if errParse != nil || !strings.EqualFold(parsed.Scheme, "https") {
			return fmt.Errorf("direct plugin sync artifact %d must use https", index)
		}
	}
	return nil
}

func (r *PluginSyncResponse) Clear() {
	if r == nil {
		return
	}
	for index := range r.Items {
		r.Items[index].Clear()
	}
	r.Items = nil

View on GitHub (pinned to 78f0c4079e)

Solutions

  1. Add at least one pinned artifact (url + digest) to the direct manifest's install plan
  2. If the plugin installs from GitHub releases, set install type to github-release instead
  3. Fix the index generator so direct entries always carry artifacts

Example fix

// before
{"install":{"type":"direct"}}

// after
{"install":{"type":"direct","artifacts":[{"url":"https://example.com/p_1.0.0_linux_amd64.zip","sha256":"..."}]}}
Defensive patterns

Strategy: validation

Validate before calling

if m.InstallType() == pluginstore.InstallTypeDirect {
    if len(pluginstore.NormalizeInstallPlan(m.Install).Artifacts) == 0 {
        return errors.New("direct manifest has no pinned artifacts")
    }
}

Try / catch

if err != nil && strings.Contains(err.Error(), "requires pinned artifacts") {
    // switch entry to github-release type or add pinned artifacts; never bypass
}

Prevention

When it happens

Trigger: Validate on a direct-install manifest whose install block is empty, has an empty artifacts array, or whose artifacts normalize away (nil entries).

Common situations: Index generator emitting install metadata only for github-release plugins but labeling everything 'direct'; manifest hand-edit that dropped the artifacts array.

Related errors


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