sxyazi/yazi · error

scheme must be 1-20 characters in kebab-case, got: {s}

Error message

scheme must be 1-20 characters in kebab-case, got: {s}

What it means

`Scheme::from_str` parses a URL scheme used in Yazi configuration: it accepts the built-ins `regular`, `search`, `sftp` and otherwise a `Custom(KebabCasedKey)` — a 1-20 character kebab-case identifier. Any other string (wrong case, over 20 chars, non-kebab characters like underscores or slashes) is rejected with this error.

Source

Thrown at yazi-shared/src/auth/scheme.rs:53

}

impl PartialEq<&Self> for Scheme {
	fn eq(&self, other: &&Self) -> bool { self == *other }
}

impl fmt::Display for Scheme {
	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { self.as_str().fmt(f) }
}

impl FromStr for Scheme {
	type Err = anyhow::Error;

	fn from_str(s: &str) -> Result<Self> {
		Ok(match s {
			"regular" => Self::Regular,
			"sftp" => Self::Sftp,
			_ if let Some(s) = KebabCasedKey::new(s) => Self::Custom(s),
			_ => bail!("scheme must be 1-20 characters in kebab-case, got: {s}"),
		})
	}
}

impl Scheme {
	pub(crate) fn as_str(&self) -> &str {
		match self {
			Self::Regular => "regular",
			Self::Sftp => "sftp",
			Self::Custom(s) => s,
		}
	}
}

impl FromLua for Scheme {
	fn from_lua(value: Value, lua: &Lua) -> mlua::Result<Self> {
		Ok(LuaString::from_lua(value, lua)?.to_str()?.parse()?)
	}

View on GitHub (pinned to 8ebf930f17)

Solutions

  1. Rewrite the scheme in lowercase kebab-case, 1-20 characters, e.g. `my-scheme`
  2. Use a built-in scheme name (`regular`, `search`, `sftp`) if that is what you meant
  3. If it came from a URL, extract only the scheme portion before the `://`

Example fix

// before
let s: Scheme = "Sftp_Plugin".parse()?;
// after
let s: Scheme = "sftp-plugin".parse()?;
Defensive patterns

Strategy: validation

Validate before calling

fn is_valid_scheme(s: &str) -> bool {
    matches!(s, "regular" | "search" | "sftp")
        || (1..=20).contains(&s.len())
        && s.chars().all(|c| c.is_ascii_lowercase() || c.is_ascii_digit() || c == '-')
        && !s.starts_with('-') && !s.ends_with('-')
}

Type guard

fn try_scheme(s: &str) -> Option<Scheme> { Scheme::from_str(s).ok() }

Try / catch

let scheme = Scheme::from_str(input)
    .with_context(|| format("bad scheme {input:?}"))?;

Prevention

When it happens

Trigger: Passing a scheme string with uppercase letters, underscores, spaces, a length > 20, or other non-kebab-case characters into any API/config that parses a Scheme (e.g. custom scheme keys in yazi.toml-related parsing, `Scheme::from_str`/DeserializeFromStr).

Common situations: Typing `MyScheme` or `my_scheme` in config instead of `my-scheme`; pasting a full URL (`sftp://host`) where only the scheme name is expected; scheme names longer than 20 characters.

Related errors


AI-assisted analysis of sxyazi/yazi@8ebf930f17 (2026-09-09). Data as JSON: /api/errors/8c6df06a311935b1. Report an issue: GitHub.