quickwit-oss/quickwit · error · io::Error (NotFound)
couldn't find parent for {}
Error message
couldn't find parent for {} What it means
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.
Source
Thrown at quickwit/quickwit-indexing/src/split_store/indexing_split_cache.rs:44
use quickwit_proto::types::SplitId;
use quickwit_storage::StorageResult;
use tantivy::Directory;
use tantivy::directory::{Advice, MmapDirectory};
use tokio::sync::Mutex;
use tracing::{debug, error, warn};
use ulid::Ulid;
use super::SplitStoreQuota;
// TODO Make this configurable.
const SPLIT_MAX_AGE: Duration = Duration::from_hours(48); // 2 days
pub fn get_tantivy_directory_from_split_bundle(
split_file: &Path,
) -> StorageResult<Box<dyn Directory>> {
let mmap_directory = MmapDirectory::open_with_madvice(
split_file.parent().ok_or_else(|| {
io::Error::new(
io::ErrorKind::NotFound,
format!("couldn't find parent for {}", split_file.display()),
)
})?,
Advice::Sequential,
)?;
let split_fileslice = mmap_directory.open_read(Path::new(&split_file))?;
Ok(Box::new(BundleDirectory::open_split(split_fileslice)?))
}
/// Returns the number of bytes held in a given directory.
async fn num_bytes_in_folder(directory_path: &Path) -> io::Result<ByteSize> {
let mut total_bytes = 0;
let mut read_dir = tokio::fs::read_dir(directory_path).await?;
while let Some(dir_entry) = read_dir.next_entry().await? {
let metadata = dir_entry.metadata().await?;
if metadata.is_file() {
total_bytes += metadata.len();View on GitHub (pinned to a39730c5cd)
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.
Example fix
// before
get_tantivy_directory_from_split_bundle(Path::new("03F8QW2X.split"))
// after
get_tantivy_directory_from_split_bundle(&cache_dir.join("03F8QW2X.split")) Defensive patterns
Strategy: validation
Validate before calling
fn has_parent(p: &Path) -> bool { p.parent().is_some() }
assert!(has_parent(&split_file), "split path must include a parent directory"); Type guard
fn is_absolute_with_parent(p: &Path) -> bool {
p.is_absolute() && p.parent().map(|p| !p.as_os_str().is_empty()).unwrap_or(false)
} Try / catch
match get_tantivy_directory_from_split_bundle(&path) {
Ok(dir) => dir,
Err(e) if e.kind() == io::ErrorKind::NotFound => {
// fall back to joining with the cache root
get_tantivy_directory_from_split_bundle(&cache_root.join(path))?
}
Err(e) => return Err(e.into()),
} Prevention
- 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
When it happens
Trigger: 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".
Common situations: 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.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- position of a Kinesis shard should never be EOF
- default search field `{default_search_field_name}` is not in
- tag fields are required to be indexed. (`{}` is not configur
- failed to send cancel command to sequencer: it is probably d
- `desired_num_pipelines` must be strictly positive
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/128edf3a5130334d.
Report an issue: GitHub.