sxyazi/yazi · error

not a URL

Error message

not a URL

What it means

Thrown by `TryFrom<Data> for UrlCow<'static>` when the `Data` value cannot be interpreted as a URL. The impl accepts `String`, `Url`, and `Bytes` variants (parsing/interpreting each as a URL) and bails "not a URL" for every other variant.

Source

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

	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;

	fn try_from(value: Data) -> Result<Self, Self::Error> {
		match value {
			Data::String(s) => s.try_into(),
			Data::Url(u) => Ok(u.into()),
			Data::Bytes(b) => b.try_into(),
			_ => bail!("not a URL"),
		}
	}
}

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

	fn try_from(value: Data) -> Result<Self, Self::Error> { UrlCow::try_from(value).map(Into::into) }
}

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

	fn try_from(value: &'a Data) -> Result<Self, Self::Error> {
		match value {
			Data::String(s) => Self::try_from(&**s),
			Data::Url(u) => Ok(u.into()),
			Data::Bytes(b) => b.as_slice().try_into(),

View on GitHub (pinned to 5f901b886b)

Solutions

  1. Verify the source produced one of String/Url/Bytes and fix the producer.
  2. Match the variant and build a `UrlBuf`/`UrlCow` only in the supported cases.
  3. If the value is a Path variant, convert via the path API (`into_url()`) instead of Data's TryFrom.

Example fix

// before
let url: UrlCow = data.try_into()?;
// after
let url: UrlCow = match data {
    d @ (Data::String(_) | Data::Url(_) | Data::Bytes(_)) => d.try_into()?,
    Data::Path(p) => p.into_url().into(),
    other => bail!("not a URL: {other:?}"),
};
Defensive patterns

Strategy: type-guard

Validate before calling

fn is_url_like(data: &Data) -> bool {
    matches!(data, Data::String(_) | Data::Url(_) | Data::Bytes(_))
}

Type guard

fn as_url(data: &Data) -> Option<UrlCow<'static>> {
    match data {
        Data::String(s) => s.to_string().try_into().ok(),
        Data::Url(u) => Some(u.clone().into()),
        _ => None,
    }
}

Try / catch

match UrlCow::try_from(data) {
    Ok(url) => use_url(url),
    Err(e) => log::warn!("expected URL payload: {e}"),
}

Prevention

When it happens

Trigger: `UrlCow::try_from(data)` where `data` is e.g. `Data::Bool`, `Data::Integer`, `Data::Number`, or `Data::Dict`.

Common situations: Plugin messages or fetch results where a field is expected to hold a file path/URL but contains a number or table — often a config key mix-up or an API change where a string field became structured data.

Related errors


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