spacedriveapp/spacedrive · error · anyhow::Error
No library selected. Use 'sd library switch' to select a lib
Error message
No library selected. Use 'sd library switch' to select a library.
What it means
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.
Source
Thrown at apps/cli/src/context.rs:116
/// Get current library info
pub async fn get_current_library_info(
&self,
) -> Result<Option<sd_core::ops::libraries::info::output::LibraryInfoOutput>> {
if let Some(_library_id) = self.library_id {
let input = sd_core::ops::libraries::info::query::LibraryInfoQueryInput {};
let info: sd_core::ops::libraries::info::output::LibraryInfoOutput =
execute_query!(self, input);
Ok(Some(info))
} else {
Ok(None)
}
}
/// Require a current library (error if none set)
pub fn require_current_library(&self) -> Result<Uuid> {
self.library_id.ok_or_else(|| {
anyhow::anyhow!("No library selected. Use 'sd library switch' to select a library.")
})
}
/// Get current library ID or throw error
pub fn get_current_library_id_or_throw(&self) -> Result<Uuid> {
self.require_current_library()
}
/// Create a new library and optionally switch to it
pub async fn create_and_switch_to_library(
&mut self,
name: String,
path: PathBuf,
set_as_current: bool,
) -> Result<Uuid> {
let input = sd_core::ops::libraries::create::input::LibraryCreateInput {
name: name.clone(),
path: Some(path),View on GitHub (pinned to 6dfeccf211)
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.
Defensive patterns
Strategy: validation
Validate before calling
async fn target_root_exists(db: &DatabaseConnection, c: &sync_conduit::Model) -> Result<bool> {
Ok(entry::Entity::find_by_id(c.target_entry_id)
.one(db)
.await?
.is_some())
} Try / catch
match svc.sync_now(conduit_id).await {
Ok(h) => Ok(h),
Err(e) if e.to_string().contains("Target entry not found") => {
prompt_recreate_target(conduit_id); // or delete_conduit
Err(e)
}
Err(e) => Err(e),
} Prevention
- 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).
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- No library selected. Use client.switchToLibrary() first.
- Library '{}' not found
- Unexpected response: ${JSON.stringify(response)}
- No library selected. Use client.switchToLibrary() first.
- Library with ID '${libraryId}' not found
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/ab49db9e9ea9b094.
Report an issue: GitHub.