spacedriveapp/spacedrive · error · CoreError

Failed to parse item_type: {}

Error message

Failed to parse item_type: {}

What it means

SpaceItem hydration (core/src/domain/space.rs:367) parses the space_item.item_type TEXT column with serde_json::from_str into ItemType. Valid stored values are externally-tagged enum JSON: "Overview", "Recents", "Favorites", "FileKinds", "Sources", "Redundancy", or objects {"Location":{"location_id":"..."}}, {"Volume":{"volume_id":"..."}}, {"Tag":{"tag_id":"..."}}, {"Path":{"sd_path":...}}, {"Source":{"source_id":"..."}}. Any other string or malformed JSON fails the whole from_ query with this error.

Source

Thrown at core/src/domain/space.rs:367

		use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};

		let item_models = space_item::Entity::find()
			.filter(space_item::Column::Uuid.is_in(ids.to_vec()))
			.all(db)
			.await?;

		let mut results = Vec::new();

		for item_model in item_models {
			// Fetch parent space to get space_id (UUID)
			let space_model = space::Entity::find_by_id(item_model.space_id)
				.one(db)
				.await?;

			let space_id = space_model.map(|s| s.uuid).unwrap_or(item_model.uuid);

			let item_type: ItemType = serde_json::from_str(&item_model.item_type).map_err(|e| {
				crate::common::errors::CoreError::Other(anyhow::anyhow!(
					"Failed to parse item_type: {}",
					e
				))
			})?;

			// Look up group UUID from group_id if present
			let group_id = if let Some(gid) = item_model.group_id {
				space_group::Entity::find_by_id(gid)
					.one(db)
					.await?
					.map(|g| g.uuid)
			} else {
				None
			};

			// Build resolved_file if entry_uuid exists
			let resolved_file = if let Some(entry_uuid) = item_model.entry_uuid {
				let entry_model = entry::Entity::find()

View on GitHub (pinned to 6dfeccf211)

Solutions

  1. Find bad rows: `SELECT id, item_type FROM space_item;` and eyeball values against the valid list above.
  2. Fix or delete the offending row: UPDATE space_item SET item_type='"Favorites"' WHERE id=...; or DELETE the row and let the user re-add the item.
  3. For renamed variants prefer #[serde(alias = "...")] so old rows keep parsing.
  4. Re-index/rebuild the space if many rows are affected (space layout is derivable from groups + items).

Example fix

# before
sqlite> SELECT item_type FROM space_item WHERE id=42;
favorites

# after
sqlite> UPDATE space_item SET item_type='"Favorites"' WHERE id=42;
Defensive patterns

Strategy: try-catch

Validate before calling

// validate before insert: item_type column must always round-trip ItemType
let encoded = serde_json::to_string(&item_type)?;
assert_eq!(
    serde_json::from_str::<ItemType>(&encoded).ok().as_ref(),
    Some(&item_type),
    "item_type encoding must be lossless"
);

Type guard

fn parse_item_type(s: &str) -> Option<ItemType> {
    serde_json::from_str(s).ok()
}

Try / catch

// skip-and-log per item so one bad row cannot break the whole space read
let item_type = match serde_json::from_str::<ItemType>(&item_model.item_type) {
    Ok(t) => t,
    Err(e) => {
        tracing::warn!(item_id = %item_model.uuid, error = %e, "dropping unparseable item");
        continue;
    }
};

Prevention

When it happens

Trigger: A space_item row whose item_type was written by another daemon version (renamed/added variant), hand-edited, or written as snake_case ('favorites' instead of '"Favorites"'); a UUID inside Location/Volume/Tag that is not valid UUID JSON also fails from_str.

Common situations: Version skew between clients and daemon sharing one library DB; downgraded builds; prototype clients writing items with a different serialization; truncated rows after a crash mid-write.

Understand the failure class

Related errors


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