{"record":{"id":"744764c8cc310b1a","repo":"quickwit-oss/quickwit","slug":"file-is-not-a-regular-file-cannot-determine","errorCode":null,"errorMessage":"file `{}` is not a regular file, cannot determine its size","messagePattern":"file `(.+?)` is not a regular file, cannot determine its size","errorType":"exception","errorClass":"StorageError","httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-storage/src/local_file_storage.rs","lineNumber":350,"sourceCode":"    }\n\n    fn uri(&self) -> &Uri {\n        &self.uri\n    }\n\n    #[tracing::instrument(\n        name = \"storage.local_file.file_num_bytes\",\n        level = \"debug\",\n        skip(self)\n    )]\n    async fn file_num_bytes(&self, path: &Path) -> StorageResult<u64> {\n        let full_path = self.full_path(path)?;\n        match tokio::fs::metadata(full_path).await {\n            Ok(metadata) => {\n                if metadata.is_file() {\n                    Ok(metadata.len())\n                } else {\n                    Err(StorageErrorKind::NotFound.with_error(anyhow::anyhow!(\n                        \"file `{}` is not a regular file, cannot determine its size\",\n                        path.display()\n                    )))\n                }\n            }\n            Err(err) => {\n                if err.kind() == ErrorKind::NotFound {\n                    Err(StorageErrorKind::NotFound.with_error(err))\n                } else {\n                    Err(err.into())\n                }\n            }\n        }\n    }\n}\n\n/// A File storage resolver\n#[derive(Clone, Debug, Default)]","sourceCodeStart":332,"sourceCodeEnd":368,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-storage/src/local_file_storage.rs#L332-L368","documentation":"`file_num_bytes` on LocalFileStorage stats the path with `tokio::fs::metadata` and refuses to return a size if the target is not a regular file (directory, fifo, socket, device). It maps that case to a NotFound StorageError rather than returning a meaningless byte count.","triggerScenarios":"Calling `Storage::file_num_bytes` (or APIs that stat objects, e.g. delete/list flows using sizes) with a path that resolves to a directory or special file instead of a regular file.","commonSituations":"Misconfigured index URI pointing at a directory instead of the index root's files; a path that was expected to be a file but is a symlink target that became a directory; passing a prefix/directory path to a size-query API.","solutions":["Verify the path points to an actual file, not a directory (`file <path>` or `ls -l`)","Correct the index/storage URI in the config so it references files, not directories","If a symlink is involved, confirm it resolves to a regular file","Handle the NotFound StorageErrorKind in the caller if probing optional paths"],"exampleFix":"// before\nlet size = storage.file_num_bytes(&dir_path).await?;\n// after\nif tokio::fs::metadata(&dir_path).await.map(|m| m.is_file()).unwrap_or(false) {\n    let size = storage.file_num_bytes(&dir_path).await?;\n}","handlingStrategy":"validation","validationCode":"let md = tokio::fs::metadata(&path).await?;\nif !md.is_file() {\n    return Err(anyhow::anyhow!(\"{} is not a regular file\", path.display()));\n}\nlet expected_len = md.len();","typeGuard":"fn is_regular_file(md: &std::fs::Metadata) -> bool { md.is_file() }","tryCatchPattern":"match storage.file_num_bytes(&path).await {\n    Ok(len) => use(len),\n    Err(e) if e.kind() == StorageErrorKind::NotFound => skip_or_recreate(path),\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Point index/storage URIs at file paths, never directories or special files","Check symlink targets resolve to regular files before wiring them into config","Probe optional paths with kind()==NotFound handling instead of assuming existence","Keep regular files and directories in clearly separated prefixes"],"tags":["storage","local-fs","stat","not-found"],"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"}