{"record":{"id":"ce153a4f9dc1ffba","repo":"BigPizzaV3/CodexPlusPlus","slug":"prepared-dream-skin-image-is-empty","errorCode":null,"errorMessage":"prepared Dream Skin image is empty","messagePattern":"prepared Dream Skin image is empty","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/codex-plus-core/src/dream_skin.rs","lineNumber":79,"sourceCode":"\n    let extension = supported_image_extension(source)?;\n    std::fs::create_dir_all(destination_dir).with_context(|| {\n        format!(\n            \"failed to create Dream Skin theme directory {}\",\n            destination_dir.display()\n        )\n    })?;\n\n    let (prepared_path, prepared_extension) = prepare_image(source, destination_dir, &extension)?;\n    let prepared_metadata = std::fs::metadata(&prepared_path).with_context(|| {\n        format!(\n            \"failed to read prepared image metadata {}\",\n            prepared_path.display()\n        )\n    })?;\n    if prepared_metadata.len() == 0 {\n        remove_prepared_copy(source, &prepared_path);\n        bail!(\"prepared Dream Skin image is empty\");\n    }\n    if prepared_metadata.len() > DREAM_SKIN_PREPARED_LIMIT {\n        remove_prepared_copy(source, &prepared_path);\n        bail!(\"prepared Dream Skin image exceeds 16 MiB\");\n    }\n\n    let destination = destination_dir.join(format!(\"{destination_stem}.{prepared_extension}\"));\n    let bytes = std::fs::read(&prepared_path)\n        .with_context(|| format!(\"failed to read prepared image {}\", prepared_path.display()))?;\n    crate::settings::atomic_write(&destination, &bytes)\n        .with_context(|| format!(\"failed to store Dream Skin image {}\", destination.display()))?;\n    remove_prepared_copy(source, &prepared_path);\n    Ok(destination)\n}\n\npub fn clear_managed_dream_skin_image(state_dir: &Path) -> anyhow::Result<()> {\n    let managed_dir = state_dir.join(MANAGED_THEME_DIR);\n    if !managed_dir.is_dir() {","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/BigPizzaV3/CodexPlusPlus/blob/f2074595a281bc057525c748175c8eb9805b0673/crates/codex-plus-core/src/dream_skin.rs#L61-L97","documentation":"macOS-only: after /usr/bin/sips converts the source to JPEG (.dream-skin-import.jpg), the prepared file is stat'd again; a zero-byte result means sips exited successfully but wrote nothing. The library deletes the empty prepared copy (remove_prepared_copy) before bailing. The source was already verified non-empty, so the loss happened during conversion.","triggerScenarios":"sips quietly emitting an empty file for a source it cannot really decode (some CMYK JPEGs, odd color profiles), or the managed directory sitting on a full or read-only volume.","commonSituations":"Disk-full on the state-dir volume; sources that Preview opens but sips' non-interactive path cannot.","solutions":["Free space or fix write permissions on the volume hosting the managed dream-skin directory","Re-save the source (Preview export) and retry the import","Reproduce with 'sips -s format jpeg SRC --out /tmp/t.jpg' and inspect the output size"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"Catch anyhow errors from import_dream_skin_image on macOS and match the 'prepared Dream Skin image is empty' message: report a conversion failure and suggest re-saving the image; the source stays untouched because the library already removed the empty prepared copy.","preventionTips":["Keep free space on the volume hosting the app state dir","Re-export exotic sources from Preview before import"],"tags":["dream-skin","macos","sips","image-conversion","rust"],"backgroundTag":"image-conversion-failed","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"}