{"record":{"id":"eea5922db08810d6","repo":"BigPizzaV3/CodexPlusPlus","slug":"normalized","errorCode":null,"errorMessage":"主题包包含重复文件：{normalized}","messagePattern":"主题包包含重复文件：(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/dream_skin_package.rs","lineNumber":875,"sourceCode":"                name.split_once('/').is_none_or(|(candidate, file)| {\n                    candidate != prefix || file.is_empty() || file.contains('/')\n                })\n            })\n        {\n            bail!(\"主题包只能包含唯一一层主题目录\");\n        }\n        Some(format!(\"{prefix}/\"))\n    };\n\n    let mut files = std::collections::BTreeMap::new();\n    for (name, content) in content_entries {\n        let normalized = prefix\n            .as_deref()\n            .and_then(|prefix| name.strip_prefix(prefix))\n            .unwrap_or(&name)\n            .to_string();\n        if files.insert(normalized.clone(), content).is_some() {\n            bail!(\"主题包包含重复文件：{normalized}\");\n        }\n    }\n    Ok(files)\n}\n\nfn validate_image_content(name: &str, bytes: &[u8]) -> anyhow::Result<()> {\n    let valid = match name {\n        \"background.png\" => bytes.starts_with(&[0x89, b'P', b'N', b'G', 0x0d, 0x0a, 0x1a, 0x0a]),\n        \"background.jpg\" => bytes.starts_with(&[0xff, 0xd8, 0xff]),\n        \"background.webp\" => {\n            bytes.len() >= 12 && &bytes[..4] == b\"RIFF\" && &bytes[8..12] == b\"WEBP\"\n        }\n        _ => false,\n    };\n    if !valid {\n        bail!(\"主题包背景图片内容与扩展名不一致：{name}\");\n    }\n    Ok(())","sourceCodeStart":857,"sourceCodeEnd":893,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/dream_skin_package.rs#L857-L893","documentation":"Deduplication guard in normalize_package_entries: after stripping the common theme-directory prefix, two entries normalize to the same file name (BTreeMap insert returned a previous value). Duplicate normalized files would silently overwrite each other, so the package is rejected.","triggerScenarios":"Thrown at crates/codex-plus-core/src/dream_skin_package.rs:875 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Remove duplicate files from the ZIP","Ensure each required file appears exactly once after prefix stripping"],"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-14T00:17:10.932Z"}