{"record":{"id":"ab49db9e9ea9b094","repo":"spacedriveapp/spacedrive","slug":"no-library-selected-use-sd-library-switch-to-se","errorCode":null,"errorMessage":"No library selected. Use 'sd library switch' to select a library.","messagePattern":"No library selected\\. Use 'sd library switch' to select a library\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"apps/cli/src/context.rs","lineNumber":116,"sourceCode":"\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)\n\tpub fn require_current_library(&self) -> Result<Uuid> {\n\t\tself.library_id.ok_or_else(|| {\n\t\t\tanyhow::anyhow!(\"No library selected. Use 'sd library switch' to select a library.\")\n\t\t})\n\t}\n\n\t/// Get current library ID or throw error\n\tpub fn get_current_library_id_or_throw(&self) -> Result<Uuid> {\n\t\tself.require_current_library()\n\t}\n\n\t/// Create a new library and optionally switch to it\n\tpub async fn create_and_switch_to_library(\n\t\t&mut self,\n\t\tname: String,\n\t\tpath: PathBuf,\n\t\tset_as_current: bool,\n\t) -> Result<Uuid> {\n\t\tlet input = sd_core::ops::libraries::create::input::LibraryCreateInput {\n\t\t\tname: name.clone(),\n\t\t\tpath: Some(path),","sourceCodeStart":98,"sourceCodeEnd":134,"githubUrl":"https://github.com/spacedriveapp/spacedrive/blob/6dfeccf2113039e35f2ce735f945e70dc3e4ea45/apps/cli/src/context.rs#L98-L134","documentation":"Returned by SyncResolver::calculate_operations when the entry row for conduit.target_entry_id is missing. It is checked right after the source root lookup, so hitting it means the source endpoint was valid but the target side dangles. The resolver needs both roots to recursively load and diff the two trees.","triggerScenarios":"sync_now / calculate_operations on a conduit whose target directory entry was deleted after the conduit was created — target folder removed and reindexed, entry row pruned, or DB restored inconsistently.","commonSituations":"Target folder on an external/unmounted volume whose entries were pruned; user deleted the target inside the app without cleaning up conduits; backup/restore asymmetry between entry and sync_conduit tables.","solutions":["Check: SELECT target_entry_id FROM sync_conduit WHERE id = <id>; verify that entry id exists.","Re-index the target location to recreate the entry, then repoint or recreate the conduit.","Otherwise remove the conduit with delete_conduit."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"async fn target_root_exists(db: &DatabaseConnection, c: &sync_conduit::Model) -> Result<bool> {\n    Ok(entry::Entity::find_by_id(c.target_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(\"Target entry not found\") => {\n        prompt_recreate_target(conduit_id); // or delete_conduit\n        Err(e)\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Watch unmount events for volumes hosting sync targets; pause conduits on unmount.","Recreate target entries by re-indexing before the next sync attempt.","Keep conduit endpoints and entry lifecycle in one transactional story (cleanup on entry delete)."],"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"}