{"record":{"id":"134918db17f19e17","repo":"BigPizzaV3/CodexPlusPlus","slug":"manifest-files-sha-256","errorCode":null,"errorMessage":"manifest.files 的 SHA-256 或大小不匹配：{}","messagePattern":"manifest\\.files 的 SHA-256 或大小不匹配：(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/dream_skin_package.rs","lineNumber":1133,"sourceCode":"            \"LICENSE.txt\" => license_bytes.context(\"manifest 声明了 LICENSE.txt 但包内缺失\")?,\n            \"manifest.sig\" => continue,\n            _ => continue,\n        };\n        let expected_media_type = match file.path.as_str() {\n            \"theme.json\" => \"application/json\",\n            \"theme.css\" => \"text/css\",\n            \"background.webp\" => \"image/webp\",\n            \"background.jpg\" => \"image/jpeg\",\n            \"background.png\" => \"image/png\",\n            \"LICENSE.txt\" => \"text/plain\",\n            _ => \"\",\n        };\n        if file.media_type != expected_media_type {\n            bail!(\"manifest.files 的 mediaType 不匹配：{}\", file.path);\n        }\n        let actual = format!(\"{:x}\", Sha256::digest(bytes));\n        if file.bytes != bytes.len() || !actual.eq_ignore_ascii_case(&file.sha256) {\n            bail!(\"manifest.files 的 SHA-256 或大小不匹配：{}\", file.path);\n        }\n    }\n    if !seen.contains(\"theme.json\") || !seen.contains(\"theme.css\") || !seen.contains(image_name) {\n        bail!(\"manifest.files 缺少必需文件\");\n    }\n    if seen.contains(\"LICENSE.txt\") != license_bytes.is_some() {\n        bail!(\"manifest.files 的 LICENSE.txt 与包内容不一致\");\n    }\n    Ok(())\n}\n\nfn valid_theme_id(value: &str) -> bool {\n    let mut chars = value.chars();\n    chars.next().is_some_and(|c| c.is_ascii_alphanumeric())\n        && value\n            .chars()\n            .all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || matches!(c, '-' | '.'))\n}","sourceCodeStart":1115,"sourceCodeEnd":1151,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/dream_skin_package.rs#L1115-L1151","documentation":"Thrown by validate_manifest_files during integrity verification: the entry's declared byte size differs from the actual extracted file length, or the SHA-256 hex digest of the bytes does not match the entry's sha256. The offending input is the manifest.files entry for {file.path} versus the real package bytes — this is tamper/corruption detection, not a format check.","triggerScenarios":"Thrown at crates/codex-plus-core/src/dream_skin_package.rs:1133 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["重新打包后用工具重算 SHA-256 并更新 manifest","确保 bytes 字段等于实际文件字节数","不要在打包后手工修改包内文件"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"f2074595a281bc057525c748175c8eb9805b0673","analyzedAt":"2026-08-23T12:52:24.489Z","contentChangedAt":"2026-08-23T12:52:24.489Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}