{"record":{"id":"128edf3a5130334d","repo":"quickwit-oss/quickwit","slug":"couldn-t-find-parent-for","errorCode":null,"errorMessage":"couldn't find parent for {}","messagePattern":"couldn't find parent for (.+?)","errorType":"exception","errorClass":"io::Error (NotFound)","httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-indexing/src/split_store/indexing_split_cache.rs","lineNumber":44,"sourceCode":"use quickwit_proto::types::SplitId;\nuse quickwit_storage::StorageResult;\nuse tantivy::Directory;\nuse tantivy::directory::{Advice, MmapDirectory};\nuse tokio::sync::Mutex;\nuse tracing::{debug, error, warn};\nuse ulid::Ulid;\n\nuse super::SplitStoreQuota;\n\n// TODO Make this configurable.\nconst SPLIT_MAX_AGE: Duration = Duration::from_hours(48); // 2 days\n\npub fn get_tantivy_directory_from_split_bundle(\n    split_file: &Path,\n) -> StorageResult<Box<dyn Directory>> {\n    let mmap_directory = MmapDirectory::open_with_madvice(\n        split_file.parent().ok_or_else(|| {\n            io::Error::new(\n                io::ErrorKind::NotFound,\n                format!(\"couldn't find parent for {}\", split_file.display()),\n            )\n        })?,\n        Advice::Sequential,\n    )?;\n    let split_fileslice = mmap_directory.open_read(Path::new(&split_file))?;\n    Ok(Box::new(BundleDirectory::open_split(split_fileslice)?))\n}\n\n/// Returns the number of bytes held in a given directory.\nasync fn num_bytes_in_folder(directory_path: &Path) -> io::Result<ByteSize> {\n    let mut total_bytes = 0;\n    let mut read_dir = tokio::fs::read_dir(directory_path).await?;\n    while let Some(dir_entry) = read_dir.next_entry().await? {\n        let metadata = dir_entry.metadata().await?;\n        if metadata.is_file() {\n            total_bytes += metadata.len();","sourceCodeStart":26,"sourceCodeEnd":62,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-indexing/src/split_store/indexing_split_cache.rs#L26-L62","documentation":"get_tantivy_directory_from_split_bundle builds a Tantivy MmapDirectory over a `.split` file and needs the file's parent directory path. `Path::parent()` returns None when the path has no parent component (e.g. a bare file name with no directory prefix), which Quickwit treats as a NotFound I/O error rather than proceeding.","triggerScenarios":"Calling get_tantivy_directory_from_split_bundle with a Path that is a plain file name like \"my_split.split\" or the filesystem root \"/\" instead of a full path such as \"/cache/dir/my_split.split\".","commonSituations":"Passing a relative bare filename constructed by string concatenation instead of joining with a cache directory; tests or tooling calling the helper directly with a synthesized name.","solutions":["Pass a fully-qualified path including the parent directory when calling get_tantivy_directory_from_split_bundle.","If the split file name is relative, join it with the intended directory first: PathBuf::from(cache_dir).join(split_file).","Check the caller's path construction (e.g. SplitFolderPath / cache_dir.join(...)) for a missing join or an empty directory component."],"exampleFix":"// before\nget_tantivy_directory_from_split_bundle(Path::new(\"03F8QW2X.split\"))\n// after\nget_tantivy_directory_from_split_bundle(&cache_dir.join(\"03F8QW2X.split\"))","handlingStrategy":"validation","validationCode":"fn has_parent(p: &Path) -> bool { p.parent().is_some() }\nassert!(has_parent(&split_file), \"split path must include a parent directory\");","typeGuard":"fn is_absolute_with_parent(p: &Path) -> bool {\n    p.is_absolute() && p.parent().map(|p| !p.as_os_str().is_empty()).unwrap_or(false)\n}","tryCatchPattern":"match get_tantivy_directory_from_split_bundle(&path) {\n    Ok(dir) => dir,\n    Err(e) if e.kind() == io::ErrorKind::NotFound => {\n        // fall back to joining with the cache root\n        get_tantivy_directory_from_split_bundle(&cache_root.join(path))?\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Always build split paths with PathBuf::join against a known cache directory","Never pass bare file names into APIs that expect a full path","Add a debug assertion validating parent presence in path-construction helpers"],"tags":["filesystem","path-handling","indexing"],"backgroundTag":"file-not-found","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}