router-for-me/CLIProxyAPI · error
artifact exceeds declared size
Error message
artifact exceeds declared size
What it means
Client.DownloadArtifact enforces the artifact's declared Size as a cap: it passes maxSize to the HTTP getter (which limits the read) and then re-checks that len(data) does not exceed it. 'artifact exceeds declared size' means the downloaded payload was larger than the size published in the plugin manifest — the download is rejected rather than trusted.
Source
Thrown at internal/pluginstore/direct.go:40
}
return Artifact{}, fmt.Errorf("artifact not found for %s/%s", goos, goarch)
}
func (c Client) DownloadArtifact(ctx context.Context, artifact Artifact) ([]byte, error) {
artifact = NormalizeInstallPlan(InstallPlan{Type: InstallTypeDirect, Artifacts: []Artifact{artifact}}).Artifacts[0]
if errValidate := ValidateArtifact(artifact); errValidate != nil {
return nil, errValidate
}
maxSize := int64(0)
if artifact.Size > 0 {
maxSize = artifact.Size
}
data, errDownload := c.get(ctx, artifact.URL, "application/octet-stream", RequestKindArtifact, maxSize)
if errDownload != nil {
return nil, errDownload
}
if maxSize > 0 && int64(len(data)) > maxSize {
return nil, fmt.Errorf("artifact exceeds declared size")
}
return data, nil
}
func VerifyArtifactChecksum(artifact Artifact, data []byte) error {
expected := strings.ToLower(strings.TrimSpace(artifact.SHA256))
if expected == "" {
return fmt.Errorf("artifact checksum missing")
}
actualBytes := sha256.Sum256(data)
actual := hex.EncodeToString(actualBytes[:])
if actual != expected {
return fmt.Errorf("artifact checksum mismatch")
}
return nil
}
View on GitHub (pinned to 78f0c4079e)
Solutions
- Refresh the plugin index/manifest so artifact.Size matches the currently published binary.
- If you publish the plugin, regenerate the manifest (size + sha256) on every release.
- Check what the URL actually serves (curl -L the artifact URL and compare Content-Length) to spot redirect/wrapping issues.
- Remove a stale zero/wrong Size only if you are certain the size is unknown — note Size == 0 disables the cap entirely.
Example fix
// before // manifest stale: size: 1200000 but binary is now 1350000 bytes artifact, data, err := fetchAndDownload(plan) // 'artifact exceeds declared size' // after // regenerate manifest from the actual release assets: // size: 1350000 // sha256: <new digest> artifact, data, err := fetchAndDownload(plan)
Defensive patterns
Strategy: validation
Validate before calling
if artifact.Size > 0 {
log.Debugf("expecting ~%d bytes for %s", artifact.Size, artifact.Name)
} Try / catch
data, err := client.DownloadArtifact(ctx, artifact)
if err != nil {
if strings.Contains(err.Error(), "exceeds declared size") {
return fmt.Errorf("manifest is stale for %s — refresh the plugin index", artifact.Name)
}
return err
} Prevention
- Regenerate size and sha256 together in the release pipeline.
- Treat a size overrun the same as a checksum mismatch: suspect, not tolerate.
When it happens
Trigger: DownloadArtifact succeeds at the HTTP layer but returns more bytes than artifact.Size (only possible when Size > 0). Typically the server ignored the Range/limit semantics, the manifest's size field is stale, or the URL was redirected to a larger file (e.g. an HTML sign-in page or a newer build).
Common situations: Manifest size field not regenerated after a plugin rebuild; a proxy or artifact registry wrapping the binary (adding headers/HTML); downloading from a URL that now serves a different, larger asset.
Related errors
- plugin_manifest_failed
- checksum mismatch for %s
- artifact checksum missing
- artifact checksum mismatch
- response exceeds maximum allowed size of %d bytes
AI-assisted analysis of router-for-me/CLIProxyAPI@78f0c4079e (2026-08-15).
Data as JSON: /api/errors/89c9b37200aae162.
Report an issue: GitHub.