sxyazi/yazi · error

Failed to downcast Data into {}

Error message

Failed to downcast Data into {}

What it means

Thrown by `Data::into_any2::<T>()` when the value is not `Data::Any` or the boxed value inside cannot be downcast to `T`. The message includes the requested type name, e.g. "Failed to downcast Data into yazi_shared::fs::File". This is a runtime type check on the type-erased `Any` payload.

Source

Thrown at yazi-shared/src/data/data.rs:287

			_ => None,
		}
	}

	pub fn into_any<T: 'static>(self) -> Option<T> {
		match self {
			Self::Any(a) => a.downcast::<T>().ok().map(|b| *b),
			_ => None,
		}
	}

	// FIXME: find a better name
	pub fn into_any2<T: 'static>(self) -> Result<T> {
		if let Self::Any(a) = self
			&& let Ok(t) = a.downcast::<T>()
		{
			Ok(*t)
		} else {
			bail!("Failed to downcast Data into {}", std::any::type_name::<T>())
		}
	}
}

impl_into_integer!(Data, i8, i16, i32, i64, isize, u8, u16, u32, u64, usize, crate::id::Id);
impl_into_number!(Data, f32, f64);

View on GitHub (pinned to 5f901b886b)

Solutions

  1. Check the concrete type with `matches!(data, Data::Any(_))` and verify the producer's payload type; pass the matching generic to `into_any2`.
  2. If multiple types are possible, try `into_any2::<T>()` for each candidate and fall back.
  3. Log `std::any::type_name::<T>()` and the actual payload type at the producer to align both sides.

Example fix

// before
let files: Vec<File> = data.into_any2()?;
// after
let files: Vec<File> = data
    .into_any2::<Vec<File>>()
    .with_context(|| format!("unexpected payload: {data:?}"))?;
Defensive patterns

Strategy: try-catch

Validate before calling

fn can_downcast<T: 'static>(data: &Data) -> bool {
    matches!(data, Data::Any(_)) // exact inner type checkable only at conversion site
}

Type guard

// Data::Any hides the inner type; guard by attempting the downcast without consuming:
fn peek<T: 'static + Clone>(data: &Data) -> Option<T> {
    if let Data::Any(a) = data { a.downcast_ref::<T>().cloned() } else { None }
}

Try / catch

match data.into_any2::<Vec<File>>() {
    Ok(v) => use_files(v),
    Err(e) => log::warn!("payload type mismatch: {e}; data was {data:?}"),
}

Prevention

When it happens

Trigger: Calling `data.into_any2::<SomeType>()` where (a) `data` is a plain variant like `String`/`Dict`, or (b) it is `Data::Any` but holds a different concrete type than requested.

Common situations: Plugin message payloads fetched with the wrong generic parameter, or two code paths agreeing on a key but not on the payload type (e.g. `Vec<String>` vs `String`).

Related errors


AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02). Data as JSON: /api/errors/cdd512bb8168e536. Report an issue: GitHub.