sxyazi/yazi · error
unknown error kind: {s}
Error message
unknown error kind: {s} What it means
`kind_from_str` deserializes an io::ErrorKind from its standard Debug/serde string form ("NotFound", "PermissionDenied", "Interrupted", etc.). Any unrecognized string bails with "unknown error kind: {s}". This fires during `Deserialize for Error` when the serialized error payload contains a kind name this version of the shim doesn't map (note some kinds like "InProgress" are commented out).
Source
Thrown at yazi-shim/src/fs/serde.rs:100
"WriteZero" => K::WriteZero,
"StorageFull" => K::StorageFull,
"NotSeekable" => K::NotSeekable,
"QuotaExceeded" => K::QuotaExceeded,
"FileTooLarge" => K::FileTooLarge,
"ResourceBusy" => K::ResourceBusy,
"ExecutableFileBusy" => K::ExecutableFileBusy,
"Deadlock" => K::Deadlock,
"CrossesDevices" => K::CrossesDevices,
"TooManyLinks" => K::TooManyLinks,
"InvalidFilename" => K::InvalidFilename,
"ArgumentListTooLong" => K::ArgumentListTooLong,
"Interrupted" => K::Interrupted,
"Unsupported" => K::Unsupported,
"UnexpectedEof" => K::UnexpectedEof,
"OutOfMemory" => K::OutOfMemory,
// "InProgress" => K::InProgress,
"Other" => K::Other,
_ => bail!("unknown error kind: {s}"),
})
}
impl Serialize for Error {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
#[derive(Serialize)]
#[serde(tag = "type", rename_all = "kebab-case")]
enum Shadow<'a> {
Kind { kind: &'a str },
Raw { code: i32 },
Dyn { kind: &'a str, code: Option<i32>, message: &'a str },
}
match self {
Self::Kind(kind) => Shadow::Kind { kind: kind_to_str(*kind) }.serialize(serializer),View on GitHub (pinned to 5f901b886b)
Solutions
- Fix the serialized payload's `kind` value to a recognized name (NotFound, PermissionDenied, Interrupted, Unsupported, UnexpectedEof, OutOfMemory, Other).
- Use "Other" as the fallback kind when serializing errors with exotic kinds.
- Upgrade or downgrade so both writer and reader use the same yazi/io version.
- If you control the producer, map unknown kinds to K::Other before serialization instead of emitting raw names.
Example fix
// before
serde_json::to_string(&err)?; // kind "CategoryNotFound" -> fails to deserialize
// after
let kind = if matches_standard_kind(err.kind()) { err.kind() } else { std::io::ErrorKind::Other };
serde_json::to_string(&io::Error::new(kind, err.to_string()))?; Defensive patterns
Strategy: fallback
Validate before calling
const KNOWN_KINDS: &[&str] = &["NotFound","PermissionDenied","Interrupted","Unsupported","UnexpectedEof","OutOfMemory","Other"];
fn is_known_kind(s: &str) -> bool { KNOWN_KINDS.contains(&s) } Try / catch
let err: ShimError = serde_json::from_str(&raw)
.unwrap_or_else(|_| ShimError::new(std::io::ErrorKind::Other, raw.clone())); Prevention
- Map exotic io::ErrorKinds to ErrorKind::Other before serializing.
- Keep writer and reader on the same yazi/Rust version.
- Sanitize third-party or hand-written payloads with is_known_kind first.
- When std adds a new ErrorKind, update the shim's match table.
When it happens
Trigger: Deserializing a serialized io::Error whose `kind` field holds a string not in the match list — e.g. a newer/older Rust stdio kind name, a platform-specific kind, or a hand-written/foreign payload with a typo'd kind string.
Common situations: Task/job state files or IPC messages written by a different yazi version whose std ErrorKind naming differs; hand-crafted test fixtures with invalid kind strings; cross-version serialization where a new ErrorKind variant round-trips through an older binary.
Related errors
- Cannot read cache stamp: {e}
- Cannot parse cache stamp: {e}
- Cannot write cache stamp: {e}
- Not a local URL: {url}
- Not a local URL: {url}
AI-assisted analysis of sxyazi/yazi@5f901b886b (2026-09-02).
Data as JSON: /api/errors/b42dc57394e9491f.
Report an issue: GitHub.