{"record":{"id":"666ec297518d1516","repo":"spacedriveapp/spacedrive","slug":"location-has-no-volume-id-volume-must-be-dete","errorCode":null,"errorMessage":"Location {} has no volume_id - volume must be detected before change detection","messagePattern":"Location (.+?) has no volume_id - volume must be detected before change detection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/src/ops/indexing/change_detection/persistent.rs","lineNumber":67,"sourceCode":"\t\tlet library = context\n\t\t\t.get_library(library_id)\n\t\t\t.await\n\t\t\t.ok_or_else(|| anyhow::anyhow!(\"Library not found: {}\", library_id))?;\n\n\t\tlet db = library.db().conn().clone();\n\n\t\tlet location_record = entities::location::Entity::find()\n\t\t\t.filter(entities::location::Column::Uuid.eq(location_id))\n\t\t\t.one(&db)\n\t\t\t.await?\n\t\t\t.ok_or_else(|| anyhow::anyhow!(\"Location not found: {}\", location_id))?;\n\n\t\tlet location_root_entry_id = location_record\n\t\t\t.entry_id\n\t\t\t.ok_or_else(|| anyhow::anyhow!(\"Location {} has no root entry\", location_id))?;\n\n\t\tlet volume_id = location_record.volume_id.ok_or_else(|| {\n\t\t\tanyhow::anyhow!(\n\t\t\t\t\"Location {} has no volume_id - volume must be detected before change detection\",\n\t\t\t\tlocation_id\n\t\t\t)\n\t\t})?;\n\n\t\tOk(Self {\n\t\t\tcontext,\n\t\t\tlibrary_id,\n\t\t\tlocation_id,\n\t\t\tlocation_root_entry_id,\n\t\t\tvolume_id,\n\t\t\tdb,\n\t\t\tvolume_backend,\n\t\t\tentry_id_cache: HashMap::new(),\n\t\t})\n\t}\n\n\tasync fn resolve_entry_id(&self, path: &Path) -> Result<Option<i32>> {","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/core/src/ops/indexing/change_detection/persistent.rs#L49-L85","documentation":"DatabaseAdapter::new requires location_record.volume_id to be non-NULL because every entry it creates is stamped with that volume. A NULL volume_id means volume detection has not run for this location yet; the message explicitly states the ordering constraint: volume must be detected before change detection starts.","triggerScenarios":"Starting change detection on a freshly added location before the volume-detection step has executed; upgrading from a schema version where volume_id did not exist and no backfill ran; volume detection failed silently earlier.","commonSituations":"Race between location creation pipeline stages (create location → detect volume → index); older databases migrated without a volume_id backfill; pluggable volume detection that skipped an unsupported filesystem.","solutions":["Run volume detection for the location first, then start change detection","Ensure the location-creation pipeline enforces the create → detect-volume → index ordering","Backfill volume_id for pre-existing locations via migration"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Ensure volume detection ran before enabling change detection\nlet loc = entities::location::Entity::find()\n    .filter(entities::location::Column::Uuid.eq(location_id))\n    .one(&db).await?;\nif let Some(l) = loc {\n    if l.volume_id.is_none() {\n        // run volume detection for this location first\n    }\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = DatabaseAdapter::new(...).await {\n    if e.to_string().contains(\"has no volume_id\") {\n        // schedule volume detection, then re-queue this job\n    }\n}","preventionTips":["Model location setup as an ordered pipeline with volume detection before indexing","Backfill volume_id in migrations that introduce it","Alert on locations stuck without volume_id after setup completes"],"tags":["indexing","database","volume","initialization","change-detection"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}