{"record":{"id":"c9af27a8ea54a0fa","repo":"router-for-me/CLIProxyAPI","slug":"artifact-checksum-missing","errorCode":null,"errorMessage":"artifact checksum missing","messagePattern":"artifact checksum missing","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/direct.go","lineNumber":48,"sourceCode":"\t}\n\tmaxSize := int64(0)\n\tif artifact.Size > 0 {\n\t\tmaxSize = artifact.Size\n\t}\n\tdata, errDownload := c.get(ctx, artifact.URL, \"application/octet-stream\", RequestKindArtifact, maxSize)\n\tif errDownload != nil {\n\t\treturn nil, errDownload\n\t}\n\tif maxSize > 0 && int64(len(data)) > maxSize {\n\t\treturn nil, fmt.Errorf(\"artifact exceeds declared size\")\n\t}\n\treturn data, nil\n}\n\nfunc VerifyArtifactChecksum(artifact Artifact, data []byte) error {\n\texpected := strings.ToLower(strings.TrimSpace(artifact.SHA256))\n\tif expected == \"\" {\n\t\treturn fmt.Errorf(\"artifact checksum missing\")\n\t}\n\tactualBytes := sha256.Sum256(data)\n\tactual := hex.EncodeToString(actualBytes[:])\n\tif actual != expected {\n\t\treturn fmt.Errorf(\"artifact checksum mismatch\")\n\t}\n\treturn nil\n}\n","sourceCodeStart":30,"sourceCodeEnd":57,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/direct.go#L30-L57","documentation":"VerifyArtifactChecksum verifies downloaded bytes against artifact.SHA256. It throws 'artifact checksum missing' when the artifact entry in the install plan has no (or only whitespace) sha256 field. The check is a hard precondition: the library refuses to install content it cannot verify, rather than skipping verification.","triggerScenarios":"Calling VerifyArtifactChecksum(artifact, data) where strings.TrimSpace(artifact.SHA256) == \"\". Happens when the plugin manifest omits the sha256 field for an artifact, or when an Artifact struct is built by hand (e.g. wrapping a URL) without a digest.","commonSituations":"Hand-authored plugin manifests where the author skipped generating digests; manifest generators that forget the sha256 field for one platform; constructing Artifact literals in code.","solutions":["Add the correct sha256 hex digest for every artifact in the plugin manifest (sha256sum of each published binary).","If you build Artifact values in code, populate the SHA256 field from your release tooling.","If you maintain the store tooling, make manifest generation fail when sha256 is empty so this is caught at publish time."],"exampleFix":"# before (manifest fragment)\nartifacts:\n  - goos: linux\n    goarch: amd64\n    url: https://example.com/p-linux-amd64\n    # sha256 missing -> 'artifact checksum missing'\n\n# after\nartifacts:\n  - goos: linux\n    goarch: amd64\n    url: https://example.com/p-linux-amd64\n    size: 1350000\n    sha256: \"<sha256 of p-linux-amd64>\"","handlingStrategy":"validation","validationCode":"if strings.TrimSpace(artifact.SHA256) == \"\" {\n    return fmt.Errorf(\"artifact %s has no sha256 in the manifest — refusing unverified install\", artifact.Name)\n}","typeGuard":"func artifactHasChecksum(a pluginstore.Artifact) bool {\n    return strings.TrimSpace(a.SHA256) != \"\"\n}","tryCatchPattern":null,"preventionTips":["Fail manifest generation when sha256 is empty.","Never skip verification for convenience — the API intentionally has no bypass."],"tags":["checksum","manifest","sha256","validation","plugin-store"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}