spacedriveapp/spacedrive · error
Library not found: {}
Error message
Library not found: {} What it means
DatabaseAdapter::new resolves the library through CoreContext::get_library(library_id) before opening its DB connection for persistent change detection. When that lookup returns None, this error is thrown: the library_id is not registered in the running daemon's library map. Change detection cannot proceed because every subsequent query would target a nonexistent database.
Source
Thrown at core/src/ops/indexing/change_detection/persistent.rs:52
location_root_entry_id: i32,
volume_id: i32,
db: sea_orm::DatabaseConnection,
volume_backend: Option<Arc<dyn crate::volume::VolumeBackend>>,
entry_id_cache: HashMap<PathBuf, i32>,
}
impl DatabaseAdapter {
pub async fn new(
context: Arc<CoreContext>,
library_id: Uuid,
location_id: Uuid,
_location_root: &Path,
volume_backend: Option<Arc<dyn crate::volume::VolumeBackend>>,
) -> Result<Self> {
let library = context
.get_library(library_id)
.await
.ok_or_else(|| anyhow::anyhow!("Library not found: {}", library_id))?;
let db = library.db().conn().clone();
let location_record = entities::location::Entity::find()
.filter(entities::location::Column::Uuid.eq(location_id))
.one(&db)
.await?
.ok_or_else(|| anyhow::anyhow!("Location not found: {}", location_id))?;
let location_root_entry_id = location_record
.entry_id
.ok_or_else(|| anyhow::anyhow!("Location {} has no root entry", location_id))?;
let volume_id = location_record.volume_id.ok_or_else(|| {
anyhow::anyhow!(
"Location {} has no volume_id - volume must be detected before change detection",
location_id
)View on GitHub (pinned to 6dfeccf211)
Solutions
- Confirm the library exists in this daemon before constructing the adapter (see validation code)
- If the daemon was just restarted, wait for library load/registration to finish before scheduling indexing jobs
- If the library was deleted, drop the queued job instead of retrying it
- Check that the library_id flows from the same source that created the library (no serialization truncation)
Defensive patterns
Strategy: validation
Validate before calling
// Resolve the library before constructing the adapter
let Some(library) = context.get_library(library_id).await else {
tracing::warn!(%library_id, "skipping change detection: library not loaded");
return Ok(());
};
// now safe: DatabaseAdapter::new(context, library_id, ...).await Try / catch
if let Err(e) = DatabaseAdapter::new(context.clone(), library_id, location_id, &root, backend).await {
if e.to_string().contains("Library not found") {
// drop the job; the library no longer exists in this daemon
return Ok(());
}
return Err(e);
} Prevention
- Never persist library ids in durable job queues without revalidating them at dequeue time
- Ensure daemon library loading completes before indexing jobs are scheduled
- Delete queued indexing jobs as part of library deletion
When it happens
Trigger: Constructing DatabaseAdapter with a stale or wrong library_id; a library deleted from another client while a change-detection job was queued; daemon restarted and the library not yet reloaded before the job re-ran.
Common situations: Job queue retains a library_id across daemon restarts; typo or UUID parse issue producing a valid-but-unknown id; library deleted concurrently with an indexer start.
Related errors
- Location not found: {}
- Location {} has no root entry
- Location {} has no volume_id - volume must be detected befor
- Entry {} not found after ID lookup
- Failed to create entry: {}
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/44dcd8bb595cb351.
Report an issue: GitHub.