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 = nilView on GitHub (pinned to 78f0c4079e)
Solutions
- Add at least one pinned artifact (url + digest) to the direct manifest's install plan
- If the plugin installs from GitHub releases, set install type to github-release instead
- 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
- Index lint: direct entries must have a non-empty artifacts array
- Default entries to the github-release install type unless artifacts are truly pinned
- Test published manifests through the client's Validate before rollout
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
- plugin sync item %d: %w
- plugin sync response contains duplicate plugin %q
- unsupported plugin sync schema_version %d
- plugin sync response missing expires_at
- plugin sync item %d auth %d: %w
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/c3d3386a1740a093.
Report an issue: GitHub.