{"record":{"id":"dade4331d3eb569e","repo":"sxyazi/yazi","slug":"fetchers-exceed-the-limit-of-max-fetchers","errorCode":null,"errorMessage":"Fetchers exceed the limit of {MAX_FETCHERS}","messagePattern":"Fetchers exceed the limit of (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"yazi-config/src/plugin/fetchers.rs","lineNumber":27,"sourceCode":"use yazi_shim::{arc_swap::{ArcSwapExt, IntoPointee}, vec::VecExt};\n\nuse super::{Fetcher, MAX_FETCHERS};\nuse crate::{mix, plugin::{FetcherArc, FetcherMatcher, fetcher_rev}};\n\n#[derive(Debug, Default, Deserialize)]\npub struct Fetchers(ArcSwap<Vec<FetcherArc>>);\n\nimpl Deref for Fetchers {\n\ttype Target = ArcSwap<Vec<FetcherArc>>;\n\n\tfn deref(&self) -> &Self::Target { &self.0 }\n}\n\nimpl TryFrom<Vec<FetcherArc>> for Fetchers {\n\ttype Error = anyhow::Error;\n\n\tfn try_from(inner: Vec<FetcherArc>) -> Result<Self> {\n\t\tensure!(inner.len() <= MAX_FETCHERS as usize, \"Fetchers exceed the limit of {MAX_FETCHERS}\");\n\n\t\tOk(Self(Self::reindex(inner).into_pointee()))\n\t}\n}\n\nimpl Fetchers {\n\tpub fn mime(&self, files: Vec<File>) -> impl Iterator<Item = (FetcherArc, Vec<File>)> {\n\t\tlet fetchers = self.load_full();\n\t\tlet mut tasks: [Vec<_>; MAX_FETCHERS as usize] = Default::default();\n\n\t\tfor file in files {\n\t\t\tlet found = FetcherMatcher::new(&fetchers, &file, \"\").find(|f| f.group == \"mime\");\n\t\t\tif let Some(fetcher) = found {\n\t\t\t\ttasks[fetcher.idx as usize].push(file);\n\t\t\t} else {\n\t\t\t\twarn!(\"No mime fetcher for {file:?}\");\n\t\t\t}\n\t\t}","sourceCodeStart":9,"sourceCodeEnd":45,"githubUrl":"https://github.com/sxyazi/yazi/blob/5f901b886b14de1f17460b6e52e9de5d67f8aba9/yazi-config/src/plugin/fetchers.rs#L9-L45","documentation":"The number of fetchers loaded from configuration is capped at `MAX_FETCHERS` (a u8-sized bound, since each fetcher's slot index is stored as a `u8`). The `TryFrom<Vec<FetcherArc>>` conversion — used when the fetcher set is built/loaded — rejects lists longer than that cap with this error. The cap exists because the `mime()` dispatch path indexes a fixed-size array of task buckets by `fetcher.idx`.","triggerScenarios":"Constructing `Fetchers` from more than `MAX_FETCHERS` fetcher entries — i.e. a yazi config (`plugin.yazi`/fetcher rules) or plugin-provided fetcher list whose length exceeds the cap.","commonSituations":"Users who stack many fetcher rules in `yazi.toml` (`[plugin]` fetchers) without pruning duplicates; plugins or setup scripts that programmatically append fetchers unboundedly before the set is committed; config merges accumulating entries across reloads.","solutions":["Reduce the number of fetcher rules in `yazi.toml` to `MAX_FETCHERS` or fewer","Merge/deduplicate rules: one fetcher entry can match multiple mime types or globs via its `if`/matchers","Increase coverage of each rule with broader globs instead of adding near-duplicate entries"],"exampleFix":"# before (yazi.toml)\n[[plugin.fetchers]]\nmime = \"text/*\"\n[[plugin.fetchers]]\nmime = \"text/*\"\n# ... (more than MAX_FETCHERS entries)\n\n// after — merge overlapping rules into one\n[[plugin.fetchers]]\nmime = \"text/*\"\n[[plugin.fetchers]]\nname = \"*.{jpg,png}\"","handlingStrategy":"validation","validationCode":"-- Lua: check fetcher count before committing config/registration\nlocal n = 0\nfor _ in pairs(my_fetchers) do n = n + 1 end\nassert(n <= 10, \"too many fetchers; merge or prune rules\") -- 10 = MAX_FETCHERS","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Count fetcher rules when editing yazi.toml and stay under MAX_FETCHERS","Merge rules matching similar conditions instead of adding duplicates","Prune obsolete rules when adding new ones"],"tags":["config-validation","limit-exceeded","fetchers"],"backgroundTag":"fetcher-limit-exceeded","analyzedSha":"5f901b886b14de1f17460b6e52e9de5d67f8aba9","analyzedAt":"2026-09-02T18:38:25.566Z","contentChangedAt":"2026-09-02T18:38:25.566Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}