sxyazi/yazi · error

not a dict

Error message

not a dict

What it means

This error comes from `TryFrom<&Data> for HashMap<DataKey, Data>` in yazi-shared's Data layer. It is thrown when a `Data` value that is not a `Data::Dict` variant is converted into a dict map. The conversion only succeeds for the `Dict` variant; every other variant bails with "not a dict".

Source

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

		value.try_into().map(|s: &str| s.to_owned())
	}
}

impl TryFrom<Data> for String {
	type Error = anyhow::Error;

	fn try_from(value: Data) -> Result<Self, Self::Error> {
		SStr::try_from(value).map(|s| s.into_owned())
	}
}

impl TryFrom<&Data> for HashMap<DataKey, Data> {
	type Error = anyhow::Error;

	fn try_from(value: &Data) -> Result<Self, Self::Error> {
		match value {
			Data::Dict(d) => Ok(d.clone()),
			_ => bail!("not a dict"),
		}
	}
}

impl TryFrom<Data> for HashMap<DataKey, Data> {
	type Error = anyhow::Error;

	fn try_from(value: Data) -> Result<Self, Self::Error> {
		match value {
			Data::Dict(d) => Ok(d),
			_ => bail!("not a dict"),
		}
	}
}

impl TryFrom<Data> for UrlCow<'static> {
	type Error = anyhow::Error;

View on GitHub (pinned to 5f901b886b)

Solutions

  1. Match on the Data value and confirm the variant is `Data::Dict` before converting.
  2. Fix the producer so it wraps the map in `Data::Dict` (e.g. `Data::Dict(map)` or the dict constructor helper).
  3. If the value may legitimately be scalar, handle each variant explicitly instead of a blanket try_into.

Example fix

// before
let map: HashMap<DataKey, Data> = (&data).try_into()?;
// after
let map: HashMap<DataKey, Data> = match &data {
    Data::Dict(_) => (&data).try_into()?,
    other => bail!("expected dict, got {other:?}"),
};
Defensive patterns

Strategy: type-guard

Validate before calling

fn is_dict(data: &Data) -> bool { matches!(data, Data::Dict(_)) }

Type guard

fn as_dict(data: &Data) -> Option<&HashMap<DataKey, Data>> {
    if let Data::Dict(d) = data { Some(d) } else { None }
}

Try / catch

match HashMap::<DataKey, Data>::try_from(&data) {
    Ok(map) => use_map(map),
    Err(e) => log::warn!("expected dict payload: {e}"),
}

Prevention

When it happens

Trigger: Calling `.try_into()` / `HashMap::try_from(&data)` on a `&Data` holding `String`, `Bytes`, `Url`, `Path`, `Bool`, `Integer`, `Number`, or `Any` instead of `Data::Dict`.

Common situations: Plugin/config code that assumes a fetch/preload payload or Lua-bound value is a table (dict) but receives a scalar or URL because the producer emitted a different variant, or a field was extracted from the wrong key.

Related errors


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