spacedriveapp/spacedrive · error
Entry {} not found after ID lookup
Error message
Entry {} not found after ID lookup What it means
find_by_path first resolves a path to an entry id via resolve_entry_id, then loads that id with find_by_id. This error means resolution returned Some(id) but the row is gone by the time the SELECT runs: a delete, a reindex that rewrote rows, or a stale closure/path mapping referencing a dead id. The two-step lookup is inherently racy under concurrent writes.
Source
Thrown at core/src/ops/indexing/change_detection/persistent.rs:166
}
let model = q.one(&self.db).await?;
Ok(model.map(|m| m.id))
}
}
#[async_trait::async_trait]
impl ChangeHandler for DatabaseAdapter {
async fn find_by_path(&self, path: &Path) -> Result<Option<EntryRef>> {
let entry_id = match self.resolve_entry_id(path).await? {
Some(id) => id,
None => return Ok(None),
};
let entry = entities::entry::Entity::find_by_id(entry_id)
.one(&self.db)
.await?
.ok_or_else(|| anyhow::anyhow!("Entry {} not found after ID lookup", entry_id))?;
let kind = match entry.kind {
0 => EntryKind::File,
1 => EntryKind::Directory,
2 => EntryKind::Symlink,
_ => EntryKind::File,
};
Ok(Some(EntryRef {
id: entry.id,
uuid: entry.uuid,
path: path.to_path_buf(),
kind,
}))
}
async fn find_by_inode(&self, inode: u64) -> Result<Option<EntryRef>> {
let inode_val = inode as i64;View on GitHub (pinned to 6dfeccf211)
Solutions
- Treat the missing row as 'not found' (return Ok(None)) so the pipeline recreates the entry instead of failing
- Check for concurrent reindex/delete jobs running against the same library
- Verify delete paths also clean entry_closure rows so resolution cannot return dead ids
Example fix
// before
let entry = entities::entry::Entity::find_by_id(entry_id)
.one(&self.db)
.await?
.ok_or_else(|| anyhow::anyhow!("Entry {} not found after ID lookup", entry_id))?;
// after: a vanished row is a normal race, not a hard failure
let Some(entry) = entities::entry::Entity::find_by_id(entry_id)
.one(&self.db)
.await?
else {
return Ok(None);
}; Defensive patterns
Strategy: try-catch
Try / catch
// A vanished row after id resolution is a benign race: treat as not-found
let entry = match entities::entry::Entity::find_by_id(entry_id).one(&db).await? {
Some(e) => e,
None => return Ok(None), // caller will recreate the entry
}; Prevention
- Avoid running reindex and change-detection concurrently on one library
- Keep delete paths consistent: remove entry and its closure rows together
- Prefer single-query path lookups over resolve-then-fetch where possible
When it happens
Trigger: A watcher event for a path whose entry was just deleted by another worker; reindex rebuilding the entry table between the id resolution and the row fetch; stale entry_closure rows pointing at removed ids.
Common situations: Concurrent indexer and watcher pipelines on the same library; a location being reindexed while change events stream in; crashed delete that removed the entry but not closure rows.
Related errors
- Entry not found after creation
- Failed to update entry: {}
- Library not found: {}
- Location not found: {}
- Location {} has no root entry
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/c76379ef27220c92.
Report an issue: GitHub.