{"record":{"id":"cf262867374dad76","repo":"BigPizzaV3/CodexPlusPlus","slug":"32-mib-zip","errorCode":null,"errorMessage":"主题包必须是 32 MiB 以内的普通 ZIP 文件","messagePattern":"主题包必须是 32 MiB 以内的普通 ZIP 文件","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/dream_skin_community.rs","lineNumber":195,"sourceCode":"        || validated.manifest.version != metadata.version\n    {\n        bail!(\"DreamSkin 主题包身份与审核元数据不一致\");\n    }\n    crate::dream_skin_library::save_validated_dream_skin_package(state_dir, &validated)\n}\n\npub fn import_theme_package(\n    state_dir: &Path,\n    archive_path: &Path,\n) -> anyhow::Result<DreamSkinThemeSummary> {\n    let metadata = std::fs::symlink_metadata(archive_path)\n        .with_context(|| format!(\"无法读取主题包：{}\", archive_path.display()))?;\n    if !metadata.file_type().is_file()\n        || metadata.file_type().is_symlink()\n        || metadata.len() == 0\n        || metadata.len() as usize > PACKAGE_BYTES_LIMIT\n    {\n        bail!(\"主题包必须是 32 MiB 以内的普通 ZIP 文件\");\n    }\n    let bytes = std::fs::read(archive_path)\n        .with_context(|| format!(\"无法读取主题包：{}\", archive_path.display()))?;\n    let validated = crate::dream_skin_package::validate_and_read_package(\n        &bytes,\n        if cfg!(windows) { \"windows\" } else { \"macos\" },\n    )?;\n    crate::dream_skin_library::save_validated_dream_skin_package(state_dir, &validated)\n}\n\npub fn save_pending_community_link(url: &str) -> anyhow::Result<String> {\n    let version_id = version_id_from_link(url)?;\n    let path = pending_link_path();\n    if let Some(parent) = path.parent() {\n        std::fs::create_dir_all(parent)?;\n    }\n    crate::settings::atomic_write(\n        &path,","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/dream_skin_community.rs#L177-L213","documentation":"import_theme_package stats the local archive with symlink_metadata and requires a regular file, not a symlink, non-zero length, and at most PACKAGE_BYTES_LIMIT (32 MiB). Anything else - directory, symlink, empty file, oversized export - is rejected up front as not a plain ZIP within 32 MiB.","triggerScenarios":"Passing a symlink to a zip, a directory, a 0-byte failed download, or a 40 MiB export; drag-dropped aliases.","commonSituations":"Cloud-sync placeholder zips; interrupted downloads; themes embedding oversized assets.","solutions":["Resolve to the real file (no symlink) and confirm it opens as a zip","Re-download when 0 bytes; compress or trim assets when over 32 MiB","Validate with 'unzip -t' before importing"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn is_importable_zip(path: &std::path::Path) -> bool {\n    match std::fs::symlink_metadata(path) {\n        Ok(m) => {\n            m.file_type().is_file()\n                && !m.file_type().is_symlink()\n                && m.len() > 0\n                && m.len() <= 32 * 1024 * 1024\n        }\n        Err(_) => false,\n    }\n}","typeGuard":"fn is_importable_zip(path: &std::path::Path) -> bool {\n    std::fs::symlink_metadata(path)\n        .map(|m| {\n            m.file_type().is_file()\n                && !m.file_type().is_symlink()\n                && m.len() > 0\n                && m.len() <= 32 * 1024 * 1024\n        })\n        .unwrap_or(false)\n}","tryCatchPattern":null,"preventionTips":["Filter pickers to regular .zip files under 32 MiB","Run 'unzip -t' on exports before import to catch corrupt archives","Materialize cloud-sync placeholder zips first"],"tags":["dreamskin","zip","file-size-limit","filesystem","rust"],"backgroundTag":"file-size-limit-exceeded","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"}