{"record":{"id":"b9d9338e69153ffd","repo":"router-for-me/CLIProxyAPI","slug":"line-d-invalid-checksum-entry","errorCode":null,"errorMessage":"line %d: invalid checksum entry","messagePattern":"line (.+?): invalid checksum entry","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/checksum.go","lineNumber":19,"sourceCode":"package pluginstore\n\nimport (\n\t\"crypto/sha256\"\n\t\"encoding/hex\"\n\t\"fmt\"\n\t\"strings\"\n)\n\nfunc ParseChecksums(data []byte) (map[string]string, error) {\n\tout := map[string]string{}\n\tfor lineNumber, rawLine := range strings.Split(string(data), \"\\n\") {\n\t\tline := strings.TrimSpace(rawLine)\n\t\tif line == \"\" || strings.HasPrefix(line, \"#\") {\n\t\t\tcontinue\n\t\t}\n\t\tfields := strings.Fields(line)\n\t\tif len(fields) < 2 {\n\t\t\treturn nil, fmt.Errorf(\"line %d: invalid checksum entry\", lineNumber+1)\n\t\t}\n\t\thash := strings.ToLower(strings.TrimSpace(fields[0]))\n\t\tif len(hash) != sha256.Size*2 {\n\t\t\treturn nil, fmt.Errorf(\"line %d: invalid sha256 length\", lineNumber+1)\n\t\t}\n\t\tif _, errDecode := hex.DecodeString(hash); errDecode != nil {\n\t\t\treturn nil, fmt.Errorf(\"line %d: invalid sha256: %w\", lineNumber+1, errDecode)\n\t\t}\n\t\tname := strings.TrimPrefix(strings.TrimSpace(fields[1]), \"*\")\n\t\tout[name] = hash\n\t}\n\treturn out, nil\n}\n\nfunc VerifyChecksum(name string, data []byte, checksums map[string]string) error {\n\texpected := strings.ToLower(strings.TrimSpace(checksums[name]))\n\tif expected == \"\" {\n\t\treturn fmt.Errorf(\"checksum for %s not found\", name)","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/checksum.go#L1-L37","documentation":"ParseChecksums hit a non-comment, non-empty line in a plugin store checksums file that split into fewer than 2 whitespace-separated fields. The expected format is sha256sum-style 'HASH  filename' per line; a single-token line means a truncated, hand-edited, or corrupt checksums file. Line numbers are 1-based and included in the message.","triggerScenarios":"The downloaded checksums file contains a lone hash with no filename, a stray word, or a wrapped/broken line — e.g. 'd41d8cd9...' alone on line 3 — during plugin install/verify.","commonSituations":"Checksums file edited by hand and a line accidentally deleted in halves; file corrupted in transit or by CRLF conversion merging lines; a store publishing a different format (e.g. SHA1SUMS) that this parser rejects.","solutions":["Regenerate the checksums file in sha256sum format: sha256sum <files> > checksums.txt","Inspect the named line for truncation or merge artifacts and fix it","If the store publishes a different checksum format, convert it or fix the store tooling"],"exampleFix":"# before (line 3)\nd41d8cd98f00b204e9800998ecf8427e\n\n# after (line 3)\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  plugin.wasm","handlingStrategy":"validation","validationCode":"func checksumFileWellFormed(data []byte) error {\n    for i, raw := range strings.Split(string(data), \"\\n\") {\n        line := strings.TrimSpace(raw)\n        if line == \"\" || strings.HasPrefix(line, \"#\") { continue }\n        if len(strings.Fields(line)) < 2 {\n            return fmt.Errorf(\"line %d will fail ParseChecksums\", i+1)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Generate checksums files exclusively with sha256sum from the artifact directory","Never hand-edit checksums files; regenerate them whenever artifacts change"],"tags":["checksum","integrity","plugin-store","file-format"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}