{"record":{"id":"1206973590c3671a","repo":"sxyazi/yazi","slug":"invalid-url-pattern-scheme-is-empty","errorCode":null,"errorMessage":"Invalid URL pattern: scheme is empty","messagePattern":"Invalid URL pattern: scheme is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"yazi-config/src/pattern.rs","lineNumber":128,"sourceCode":"\tAny,\n\tLocal,\n\tRemote,\n\n\tCustom(String),\n}\n\nimpl PatternScheme {\n\tfn parse(s: &str) -> Result<(Self, usize)> {\n\t\tlet Some((s, _)) = s.split_once(\"://\") else {\n\t\t\treturn Ok((Self::Any, 0));\n\t\t};\n\n\t\tlet scheme = match s {\n\t\t\t\"*\" => Self::Any,\n\t\t\t\"local\" => Self::Local,\n\t\t\t\"remote\" => Self::Remote,\n\n\t\t\t\"\" => bail!(\"Invalid URL pattern: scheme is empty\"),\n\t\t\tother => Self::Custom(other.to_owned()),\n\t\t};\n\n\t\tOk((scheme, s.len() + 3))\n\t}\n\n\t#[inline]\n\tfn matches(&self, auth: &Auth) -> bool {\n\t\tmatch self {\n\t\t\tSelf::Any => true,\n\t\t\tSelf::Local => auth.is_local(),\n\t\t\tSelf::Remote => auth.is_remote(),\n\t\t\tSelf::Custom(name) => auth.scheme == name,\n\t\t}\n\t}\n}\n\n// --- Tests","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/sxyazi/yazi/blob/8ebf930f1796ae2076b7d6b0c5e93a1002c18134/yazi-config/src/pattern.rs#L110-L146","documentation":"Yazi's URL pattern parser (yazi-config/src/pattern.rs:130) parses a scheme portion of a glob/match pattern, e.g. `local/path/**` or `remote:bucket`. An empty scheme string means the pattern started with the scheme separator but had nothing before it, so the parser cannot determine which URL namespace the pattern applies to and bails.","triggerScenarios":"Calling pattern parsing with a string whose scheme part before the `://` separator is empty, e.g. a pattern like `://foo` or `:*/x` where the portion before the separator is the empty string; the match arm `\"\" => bail!(...)` fires during `parse`.","commonSituations":"Hand-written yazi.toml / rules entries with a typo such as a leading `://`, or programmatically built patterns where the scheme variable was empty because it was never set or was stripped by earlier string handling.","solutions":["Fix the pattern string so it either has a non-empty scheme (e.g. `local/...`, `remote/...`) or no scheme separator at all.","If any scheme should match, use the wildcard `*` as the scheme instead of leaving it empty.","Validate/trim the scheme in code before constructing the pattern, rejecting or defaulting empty values."],"exampleFix":"// before\nPattern::parse(\"://downloads/**\")\n// after\nPattern::parse(\"*/downloads/**\")  // or \"local/downloads/**\"","handlingStrategy":"validation","validationCode":"fn valid_scheme(p: &str) -> bool {\n    match p.split_once(\"://\") {\n        Some((scheme, _)) => !scheme.is_empty(),\n        None => true, // no scheme separator is fine\n    }\n}\nassert!(valid_scheme(\"local/d/**\"));\nassert!(!valid_scheme(\"://d/**\"));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never write patterns with a leading `://`; use `*` as an any-scheme wildcard.","Trim and inspect scheme variables before interpolating them into pattern strings.","Test config patterns with the parser at startup rather than failing at match time."],"tags":["config","url-pattern","parsing","validation"],"backgroundTag":"empty-url-scheme","analyzedSha":"8ebf930f1796ae2076b7d6b0c5e93a1002c18134","analyzedAt":"2026-09-09T22:26:16.379Z","contentChangedAt":"2026-09-09T22:26:16.379Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}