{"record":{"id":"a06ca2c1b86f74d8","repo":"spacedriveapp/spacedrive","slug":"failed-to-get-metadata-via-backend","errorCode":null,"errorMessage":"Failed to get metadata via backend: {}","messagePattern":"Failed to get metadata via backend: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/src/ops/indexing/change_detection/handler.rs","lineNumber":127,"sourceCode":"\t\t\t}\n\t\t}\n\t}\n}\n\n/// Evaluates indexing rules to determine if a path should be skipped.\npub async fn should_filter_path(\n\tpath: &Path,\n\trule_toggles: RuleToggles,\n\tlocation_root: &Path,\n\tbackend: Option<&Arc<dyn crate::volume::VolumeBackend>>,\n) -> Result<bool> {\n\tlet ruler = build_default_ruler(rule_toggles, location_root, path).await;\n\n\tlet metadata = if let Some(backend) = backend {\n\t\tbackend\n\t\t\t.metadata(path)\n\t\t\t.await\n\t\t\t.map_err(|e| anyhow::anyhow!(\"Failed to get metadata via backend: {}\", e))?\n\t} else {\n\t\tlet fs_meta = tokio::fs::metadata(path).await?;\n\t\tcrate::volume::backend::RawMetadata {\n\t\t\tkind: if fs_meta.is_dir() {\n\t\t\t\tEntryKind::Directory\n\t\t\t} else if fs_meta.is_symlink() {\n\t\t\t\tEntryKind::Symlink\n\t\t\t} else {\n\t\t\t\tEntryKind::File\n\t\t\t},\n\t\t\tsize: fs_meta.len(),\n\t\t\tmodified: fs_meta.modified().ok(),\n\t\t\tcreated: fs_meta.created().ok(),\n\t\t\taccessed: fs_meta.accessed().ok(),\n\t\t\tinode: None,\n\t\t\tpermissions: None,\n\t\t}\n\t};","sourceCodeStart":109,"sourceCodeEnd":145,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/indexing/change_detection/handler.rs#L109-L145","documentation":"Thrown by should_filter_path when the VolumeBackend's metadata() call fails while change detection decides whether a path is filtered. The backend abstraction fronts non-local volumes (removable/network), so any I/O failure at the metadata call is wrapped here. The path never gets evaluated against the ruler because the kind/size/modified data it needs could not be fetched.","triggerScenarios":"Calling should_filter_path with Some(backend) while the volume behind that backend is unavailable: backend.metadata(path) returns Err. Typical when an indexer or watcher event fires after a USB eject, an SMB/NFS disconnect, or a permission change on the mount root.","commonSituations":"Removable drive unplugged mid-index; network share offline at scan time; a VolumeBackend instance kept alive after the volume was unmounted; watcher events queued from a device that disappeared before processing.","solutions":["Verify the volume is still mounted (re-run volume detection) before starting or resuming change detection for this location","Check the VolumeBackend implementation's own logs for the underlying I/O error this message wraps","If the volume is gone, cancel/abort the indexing job for that location rather than retrying the same path","For local filesystems, pass None as backend so the tokio::fs::metadata fallback path is used"],"exampleFix":"// before\nlet metadata = backend\n    .metadata(path)\n    .await\n    .map_err(|e| anyhow::anyhow!(\"Failed to get metadata via backend: {}\", e))?;\n\n// after: include the path so operators can tell which volume/file died\nlet metadata = backend\n    .metadata(path)\n    .await\n    .map_err(|e| anyhow::anyhow!(\"Failed to get metadata via backend for {}: {} (is the volume still mounted?)\", path.display(), e))?;","handlingStrategy":"validation","validationCode":"// Before indexing/change detection, confirm the volume answers metadata at the root\nif let Some(backend) = &backend {\n    if backend.metadata(location_root).await.is_err() {\n        // volume is unreachable; abort the scan for this location instead of per-path failures\n        return Ok(());\n    }\n}","typeGuard":null,"tryCatchPattern":"match should_filter_path(path, toggles, root, backend.as_deref()).await {\n    Ok(filtered) => { /* continue */ }\n    Err(e) if e.to_string().contains(\"Failed to get metadata via backend\") => {\n        tracing::warn!(error = %e, \"volume metadata failed; skipping path and marking volume suspect\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Run volume detection/mount checks before every indexing session on removable or network volumes","Watch for volume-removal events and cancel in-flight indexing jobs for that location","Prefer passing None for purely local locations so the tokio::fs path is used"],"tags":["indexing","filesystem","volume-backend","metadata","change-detection"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}