{"record":{"id":"e86e5e724a971b69","repo":"spacedriveapp/spacedrive","slug":"library-not-found","errorCode":null,"errorMessage":"Library '{}' not found","messagePattern":"Library '(.+?)' not found","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"apps/cli/src/context.rs","lineNumber":95,"sourceCode":"\t\t\t.set_current_library(library_id, &self.data_dir)\n\t}\n\n\t/// Switch to a library by name\n\tpub async fn switch_to_library_named(&mut self, name: &str) -> Result<()> {\n\t\tlet libs: Vec<sd_core::ops::libraries::list::output::LibraryInfo> = execute_core_query!(\n\t\t\tself,\n\t\t\tsd_core::ops::libraries::list::query::ListLibrariesInput {\n\t\t\t\tinclude_stats: false\n\t\t\t}\n\t\t);\n\n\t\tif let Some(lib) = libs.iter().find(|lib| lib.name == name) {\n\t\t\tself.library_id = Some(lib.id);\n\t\t\tself.cli_config\n\t\t\t\t.set_current_library(lib.id, &self.data_dir)?;\n\t\t\tOk(())\n\t\t} else {\n\t\t\tanyhow::bail!(\"Library '{}' not found\", name)\n\t\t}\n\t}\n\n\t/// Get current library info\n\tpub async fn get_current_library_info(\n\t\t&self,\n\t) -> Result<Option<sd_core::ops::libraries::info::output::LibraryInfoOutput>> {\n\t\tif let Some(_library_id) = self.library_id {\n\t\t\tlet input = sd_core::ops::libraries::info::query::LibraryInfoQueryInput {};\n\t\t\tlet info: sd_core::ops::libraries::info::output::LibraryInfoOutput =\n\t\t\t\texecute_query!(self, input);\n\t\t\tOk(Some(info))\n\t\t} else {\n\t\t\tOk(None)\n\t\t}\n\t}\n\n\t/// Require a current library (error if none set)","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/apps/cli/src/context.rs#L77-L113","documentation":"Returned by SyncResolver::calculate_operations when the entry row for conduit.source_entry_id no longer exists. Unlike the create-time validation in conduit.rs, this fires at sync time: the conduit row persists but its source endpoint has been deleted from the entries table.","triggerScenarios":"Running sync_now (which calls resolver.calculate_operations) on a conduit whose source directory entry was deleted — source folder removed from disk and reindexed away, or the entry row manually deleted.","commonSituations":"User deletes or renames the synced folder outside the app; a reindex prunes entries for unmounted/removed locations; DB restored from a backup that dropped entries but kept conduits.","solutions":["Check the reference: SELECT source_entry_id FROM sync_conduit WHERE id = <id>; then SELECT id FROM entry WHERE id = <that>.","If the directory still exists on disk, re-index its location to recreate the entry, then update the conduit to the new entry id.","If it is gone for good, delete the conduit (delete_conduit) to stop sync attempts."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Validate conduit endpoints before calculating operations.\nasync fn source_root_exists(db: &DatabaseConnection, c: &sync_conduit::Model) -> Result<bool> {\n    Ok(entry::Entity::find_by_id(c.source_entry_id)\n        .one(db)\n        .await?\n        .is_some())\n}","typeGuard":null,"tryCatchPattern":"match svc.sync_now(conduit_id).await {\n    Ok(h) => Ok(h),\n    Err(e) if e.to_string().contains(\"Source entry not found\") => {\n        disable_or_delete_conduit(conduit_id); // stop retrying a broken pair\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Delete or disable conduits when their source directory entry is removed by reindex.","After restoring a DB backup, audit conduits for dangling endpoint ids.","Log conduit id plus endpoint ids when resolution fails."],"tags":["rust","file-sync","dangling-reference","not-found"],"backgroundTag":null,"analyzedSha":"6dfeccf2113039e35f2ce735f945e70dc3e4ea45","analyzedAt":"2026-08-16T11:26:17.074Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}