{"record":{"id":"661a1c330b42f035","repo":"astrid-runtime/astrid","slug":"legacy-capsule-contains-special-file","errorCode":null,"errorMessage":"legacy capsule contains special file {}","messagePattern":"legacy capsule contains special file (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-capsule-install/src/storage.rs","lineNumber":711,"sourceCode":"    fs::create_dir_all(destination)?;\n    for (path, metadata) in read_dir_sorted(source)? {\n        let relative = path\n            .file_name()\n            .ok_or_else(|| anyhow::anyhow!(\"legacy capsule entry has no name\"))?;\n        let destination = destination.join(relative);\n        if metadata.file_type().is_symlink() {\n            bail!(\"legacy capsule contains symlink {}\", path.display());\n        }\n        if metadata.is_dir() {\n            copy_legacy_tree(&path, &destination)?;\n        } else if metadata.is_file() {\n            let name = path.file_name().and_then(|name| name.to_str());\n            if matches!(name, Some(\"meta.json\" | \"authority.json\" | \".env.json\")) {\n                continue;\n            }\n            fs::copy(path, destination)?;\n        } else {\n            bail!(\"legacy capsule contains special file {}\", path.display());\n        }\n    }\n    Ok(())\n}\n\nfn manifest_identity(source_dir: &Path) -> anyhow::Result<(String, String)> {\n    let manifest = fs::read_to_string(source_dir.join(\"Capsule.toml\"))\n        .with_context(|| format!(\"read capsule manifest from {}\", source_dir.display()))?;\n    let value: toml::Value = toml::from_str(&manifest).context(\"parse capsule manifest\")?;\n    let id = value\n        .get(\"package\")\n        .and_then(|package| package.get(\"name\"))\n        .and_then(toml::Value::as_str)\n        .ok_or_else(|| anyhow::anyhow!(\"Capsule.toml has no package.name\"))?;\n    let version = value\n        .get(\"package\")\n        .and_then(|package| package.get(\"version\"))\n        .and_then(toml::Value::as_str)","sourceCodeStart":693,"sourceCodeEnd":729,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-capsule-install/src/storage.rs#L693-L729","documentation":"Raised by copy_legacy_tree when a legacy capsule entry is neither a directory nor a regular file (e.g. a FIFO, socket, or device node). The library only copies regular files and directories into canonical legacy archives; anything else is rejected as unsafe/unsupported.","triggerScenarios":"Migrating a legacy capsule tree that contains special filesystem objects — named pipes, unix sockets, device files — at any depth under the capsule directory.","commonSituations":"Capsule directory previously hosted a running process that left sockets/FIFOs behind; a bad backup/restore produced device nodes; users pointed a capsule dir at a mount point with odd entries.","solutions":["Remove or relocate the special file named in the message out of the capsule directory.","Stop any process using the socket/FIFO inside the capsule tree and clean up before re-running the migration.","Restore the capsule from a clean source that contains only regular files and directories."],"exampleFix":"# before: stale socket inside the capsule\ncapsule/runtime.sock\n\n# after: remove it\nrm capsule/runtime.sock","handlingStrategy":"validation","validationCode":"fn has_special_files(dir: &Path) -> std::io::Result<bool> {\n    Ok(walkdir(dir).any(|e| !e.file_type().is_file() && !e.file_type().is_dir() && !e.file_type().is_symlink()))\n}","typeGuard":"fn is_fs_special(md: &std::fs::Metadata) -> bool {\n    !md.is_file() && !md.is_dir() && !md.is_symlink()\n}","tryCatchPattern":"match migrate(...) {\n    Err(e) if e.to_string().contains(\"special file\") => { cleanup_runtime_artifacts(&dir)?; retry(); }\n    other => other?,\n}","preventionTips":["Stop processes that create sockets/FIFOs in the capsule dir before archiving","Clean runtime artifacts (e.g. *.sock) before migration","Restore capsules from clean, regular-file-only backups"],"tags":["special-file","archive-validation","capsule"],"backgroundTag":"unsupported-operation","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}