spacedriveapp/spacedrive · warning · anyhow::Error
Failed to dispatch thumbnail job: {}
Error message
Failed to dispatch thumbnail job: {} What it means
library.jobs().dispatch(job) failed while dispatching a ThumbnailJob after a sidecar was stored. The job system for that library rejected the dispatch, most commonly because the jobs actor or its channel is already closed (library shutting down) or the job manager was never started. Thumbnails are regenerable, so failing the sidecar store on this is disproportionate.
Source
Thrown at core/src/service/sidecar_manager.rs:319
ThumbnailJob, ThumbnailJobConfig, ThumbnailVariants,
};
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
// Find an entry with this content_uuid
let entry_with_content = entry::Entity::find()
.find_also_related(content_identity::Entity)
.filter(content_identity::Column::Uuid.eq(*content_uuid))
.one(db.conn())
.await?;
if let Some((entry_model, _)) = entry_with_content {
if let Some(entry_uuid) = entry_model.uuid {
// Dispatch thumbnail job for this specific entry
let config = ThumbnailJobConfig::default();
let job = ThumbnailJob::for_entries(vec![entry_uuid], config);
library.jobs().dispatch(job).await.map_err(|e| {
anyhow::anyhow!("Failed to dispatch thumbnail job: {}", e)
})?;
info!(
"Dispatched thumbnail job for {} {} {} (content: {})",
kind.as_str(),
variant.as_str(),
format.as_str(),
content_uuid
);
}
}
}
_ => {
// For other sidecar types, just log for now
// TODO: Implement dispatch for OCR, transcripts, etc.
info!(
"Enqueued sidecar generation: {} {} {} for {} (no job dispatch yet)",
kind.as_str(),View on GitHub (pinned to 6dfeccf211)
Solutions
- Log and continue: the thumbnail can be regenerated on the next scan or explicit request
- Ensure the library's job system is running before sidecar-triggered dispatches
- On shutdown, drain or cancel pending dispatches before closing the job channel
Example fix
// before
library.jobs().dispatch(job).await.map_err(|e| anyhow::anyhow!("Failed to dispatch thumbnail job: {}", e))?;
// after
if let Err(e) = library.jobs().dispatch(job).await {
warn!(error = %e, "thumbnail dispatch failed, will regenerate on next scan");
} Defensive patterns
Strategy: fallback
Validate before calling
// Only dispatch when the job system is live
if library.jobs().is_running().await {
library.jobs().dispatch(job).await?;
} else {
warn!("job system not running, thumbnail deferred");
} Try / catch
if let Err(e) = library.jobs().dispatch(job).await {
if e.to_string().contains("Failed to dispatch thumbnail job") || e.to_string().contains("closed") {
warn!(error = %e, "thumbnail dispatch failed, will regenerate on next scan");
} else {
return Err(e.into());
}
} Prevention
- Treat thumbnail dispatch as best-effort: log and continue, thumbnails are regenerable
- Ensure the library job system is running before sidecar-triggered dispatches
- Drain or cancel pending dispatches before closing the job channel at shutdown
When it happens
Trigger: Library closing while sidecar writes trigger thumbnail dispatches; using a library handle whose job actor stopped after a restart; the dispatch channel already closed.
Common situations: Shutdown races at library close; background jobs racing daemon restarts.
Related errors
- Library {} not initialized
- Invalid sidecar format: {}
- Invalid sidecar status: {}
- Source entry not found
- Operation cancelled
AI-assisted analysis of spacedriveapp/spacedrive@6dfeccf211 (2026-08-16).
Data as JSON: /api/errors/1a881a55371cee95.
Report an issue: GitHub.