{"record":{"id":"6dee1e50feadf8e6","repo":"astrid-runtime/astrid","slug":"representation-namespace-entry-is-redirected-or-ha","errorCode":null,"errorMessage":"representation namespace entry is redirected or has the wrong type","messagePattern":"representation namespace entry is redirected or has the wrong type","errorType":"exception","errorClass":"io::Error","httpStatus":null,"severity":"error","filePath":"crates/astrid-storage/src/engine/durable/representations/contiguous/namespace.rs","lineNumber":94,"sourceCode":"    #[cfg(unix)]\n    {\n        directory.open(Path::new(\".\"))?.into_std().sync_all()\n    }\n\n    #[cfg(not(unix))]\n    {\n        let _ = directory;\n        Ok(())\n    }\n}\n\nfn reject_redirect(parent: &Dir, name: &Path, directory: bool) -> io::Result<()> {\n    let metadata = parent.symlink_metadata(name)?;\n    if is_redirect(&metadata)\n        || (directory && !metadata.is_dir())\n        || (!directory && !metadata.is_file())\n    {\n        return Err(io::Error::new(\n            io::ErrorKind::InvalidData,\n            \"representation namespace entry is redirected or has the wrong type\",\n        ));\n    }\n    Ok(())\n}\n\npub(in crate::engine::durable::representations) fn configure_no_follow(options: &mut OpenOptions) {\n    #[cfg(unix)]\n    {\n        use cap_std::fs::OpenOptionsExt as _;\n        options.custom_flags(libc::O_NOFOLLOW | libc::O_NONBLOCK);\n    }\n    #[cfg(windows)]\n    {\n        use cap_std::fs::OpenOptionsExt as _;\n        use windows_sys::Win32::Storage::FileSystem::FILE_FLAG_OPEN_REPARSE_POINT;\n        options.custom_flags(FILE_FLAG_OPEN_REPARSE_POINT);","sourceCodeStart":76,"sourceCodeEnd":112,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-storage/src/engine/durable/representations/contiguous/namespace.rs#L76-L112","documentation":"reject_redirect inspects symlink_metadata of a namespace entry and rejects it if it is a symlink/redirect or has the wrong type (directory expected when directory=true, regular file otherwise). This InvalidData error guards the contiguous-representation namespace against redirected or mistyped entries. It runs before each directory open in open_component.","triggerScenarios":"Calling open_component (and thereby reject_redirect) on an entry that is a symlink, or a file where a directory is expected (or vice versa); also triggered by filesystem redirection detected by is_redirect.","commonSituations":"Symlinking namespace entries to share representations between stores; a migration script created files where directories belong; tampering in a shared store directory.","solutions":["Replace the symlink or mistyped entry with the correct object type (real directory or regular file)","Do not create symlinks inside the representation namespace","Fix the migration/tooling script that produced the wrong entry type","Tighten store-directory permissions against third-party modification"],"exampleFix":"// before\nln -s ../other-store/rep store/rep/abc\n// after\nrm store/rep/abc && mkdir store/rep/abc","handlingStrategy":"validation","validationCode":"fn check_entry_type(p: &Path, want_dir: bool) -> io::Result<()> {\n    let md = std::fs::symlink_metadata(p)?;\n    let ok = if want_dir { md.is_dir() } else { md.is_file() };\n    if !ok || md.file_type().is_symlink() {\n        return Err(io::Error::new(io::ErrorKind::InvalidData, \"redirected or wrong type\"));\n    }\n    Ok(())\n}","typeGuard":"fn is_correct_entry(p: &Path, want_dir: bool) -> bool {\n    std::fs::symlink_metadata(p)\n        .map(|m| !m.file_type().is_symlink() && (if want_dir { m.is_dir() } else { m.is_file() }))\n        .unwrap_or(false)\n}","tryCatchPattern":"match open_result {\n    Err(e) if e.kind() == io::ErrorKind::InvalidData => {\n        // fix entry type / remove symlink, then retry\n    }\n    r => r,\n}","preventionTips":["Never symlink namespace entries","Ensure migration scripts create the correct entry types (dirs vs files)","Run pre-open layout validation on the representation tree","Lock down store-directory write permissions"],"tags":["io","filesystem","symlink"],"backgroundTag":"symlink-detected-in-path","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"}