{"record":{"id":"f8e32cc5baa6fb46","repo":"Hmbown/CodeWhale","slug":"invalid-sha256-manifest-line-trimmed","errorCode":null,"errorMessage":"invalid SHA256 manifest line {}: {trimmed}","messagePattern":"invalid SHA256 manifest line (.+?): (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/cli/src/update.rs","lineNumber":1154,"sourceCode":"\nfn select_checksum_manifest_asset(release: &Release) -> Option<&Asset> {\n    release\n        .assets\n        .iter()\n        .find(|asset| asset.name == CHECKSUM_MANIFEST_ASSET)\n}\n\nfn parse_checksum_manifest(text: &str) -> Result<HashMap<String, String>> {\n    let mut checksums = HashMap::new();\n\n    for (index, line) in text.lines().enumerate() {\n        let trimmed = line.trim();\n        if trimmed.is_empty() {\n            continue;\n        }\n\n        if trimmed.len() < 66 {\n            bail!(\"invalid SHA256 manifest line {}: {trimmed}\", index + 1);\n        }\n\n        let (hash, rest) = trimmed.split_at(64);\n        if !hash.chars().all(|ch| ch.is_ascii_hexdigit())\n            || rest.is_empty()\n            || !rest.chars().next().is_some_and(char::is_whitespace)\n        {\n            bail!(\"invalid SHA256 manifest line {}: {trimmed}\", index + 1);\n        }\n\n        let mut asset_name = rest.trim_start();\n        if let Some(stripped) = asset_name.strip_prefix('*') {\n            asset_name = stripped;\n        }\n        if asset_name.is_empty() {\n            bail!(\"invalid SHA256 manifest line {}: {trimmed}\", index + 1);\n        }\n","sourceCodeStart":1136,"sourceCodeEnd":1172,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/0c42157ee52f9d55af2b506d71b46249910f77d3/crates/cli/src/update.rs#L1136-L1172","documentation":"parse_checksum_manifest rejects a nonempty manifest line shorter than 66 bytes: a valid line needs at least 64 hex characters plus a whitespace separator plus a nonempty filename. Short lines usually mean the wrong digest algorithm (MD5 gives 32 hex chars) or a truncated/garbled checksums file.","triggerScenarios":"Self-update (or tests calling parse_checksum_manifest) where the downloaded checksum manifest contains MD5/CRC-style short hashes, truncated lines, or stray short text instead of sha256sum-format lines.","commonSituations":"Release pipelines that emit md5sums.txt by default, hand-written manifests, CI steps that truncate lines, or a proxy/HTML error page replacing the manifest body (though that more often trips the not-valid-UTF-8 or hex check).","solutions":["Regenerate the manifest with sha256sum (64 hex chars per line): sha256sum <assets> > SHA256SUMS","Check the reported line number in the message against the file to see the offending content","If you are a consumer, report the broken manifest for that release tag; do not bypass checksum verification","Ensure no tool rewraps or truncates the manifest before upload"],"exampleFix":"# before\n1b0a9c...e2  codewhale-linux-x64.tar.gz   # 32-hex MD5, line < 66 chars\n\n# after\n9f2c86d1...full-64-hex...01  codewhale-linux-x64.tar.gz","handlingStrategy":"validation","validationCode":"// Validate a manifest before handing it to the updater:\nfn manifest_lines_valid(text: &str) -> bool {\n    text.lines().all(|line| {\n        let t = line.trim();\n        t.is_empty()\n            || (t.len() >= 66\n                && t.as_bytes()[..64].iter().all(|b| b.is_ascii_hexdigit())\n                && t.as_bytes()[64].is_ascii_whitespace())\n    })\n}","typeGuard":null,"tryCatchPattern":"Catch the parse error, use the printed 1-based line number to locate the bad entry, fix or regenerate the manifest, and re-run; never catch-and-ignore to download without checksums.","preventionTips":["Generate manifests with sha256sum, not md5sum or custom scripts","Validate manifests in CI before publishing releases","Check line length: 64 hex + separator + nonempty name"],"tags":["sha256","manifest","parsing","release"],"backgroundTag":"sha256sums-manifest-malformed","analyzedSha":"0c42157ee52f9d55af2b506d71b46249910f77d3","analyzedAt":"2026-08-20T21:50:45.477Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}