{"record":{"id":"5d840910c4ab0d34","repo":"router-for-me/CLIProxyAPI","slug":"line-d-invalid-sha256-length","errorCode":null,"errorMessage":"line %d: invalid sha256 length","messagePattern":"line (.+?): invalid sha256 length","errorType":"http","errorClass":null,"httpStatus":502,"severity":"error","filePath":"internal/pluginstore/checksum.go","lineNumber":23,"sourceCode":"\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)\n\t}\n\tactualBytes := sha256.Sum256(data)\n\tactual := hex.EncodeToString(actualBytes[:])\n\tif actual != expected {","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/pluginstore/checksum.go#L5-L41","documentation":"A checksums-file line parsed into fields, but the first field (the hash) is not exactly 64 hex characters (sha256.Size*2). ParseChecksums only accepts SHA-256 digests; a 40-char SHA-1, 128-char SHA-512, or truncated hash on the reported line triggers this error.","triggerScenarios":"The checksums file was generated with sha1sum/shasum -a 1 or md5sum instead of sha256sum, or a hash was copy-truncated, on the line named in the error.","commonSituations":"Store tooling defaults to SHA-1 on older distros; developer used 'shasum' without -a 256; manual paste dropped characters; mixed-format file where some lines are SHA-1.","solutions":["Regenerate the file with sha256sum (or sha256sum -b for binary mode)","Fix or remove the specific malformed line indicated by the line number","Ensure no other digest algorithms are mixed into the same file"],"exampleFix":"# before\nda39a3ee5e6b4b0d3255bfef95601890afd80709  plugin.wasm  # sha1, 40 chars\n\n# after\ne3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855  plugin.wasm","handlingStrategy":"validation","validationCode":"func allHashesAreSha256(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        h := strings.ToLower(strings.Fields(line)[0])\n        if len(h) != 64 {\n            return fmt.Errorf(\"line %d uses a non-sha256 digest\", i+1)\n        }\n    }\n    return nil\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use sha256sum (not shasum, md5sum, or sha1sum) when publishing store artifacts","CI-check published checksums files: every hash must be 64 lowercase hex chars"],"tags":["checksum","sha256","plugin-store","file-format"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}