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

  1. Confirm the library exists in this daemon before constructing the adapter (see validation code)
  2. If the daemon was just restarted, wait for library load/registration to finish before scheduling indexing jobs
  3. If the library was deleted, drop the queued job instead of retrying it
  4. 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

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


AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16). Data as JSON: /api/errors/44dcd8bb595cb351. Report an issue: GitHub.