{"record":{"id":"1e61b96ce44f30fe","repo":"jdx/mise","slug":"bootstrap-config-roots-did-not-match-any-config","errorCode":null,"errorMessage":"[bootstrap].config_roots did not match any config roots","messagePattern":"\\[bootstrap\\]\\.config_roots did not match any config roots","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/config/mod.rs","lineNumber":1556,"sourceCode":"        cf.bootstrap_config()\n            .and_then(|bootstrap| bootstrap.config_roots.map(|patterns| (path, patterns)))\n    }) else {\n        return Ok(vec![]);\n    };\n    if patterns.is_empty() {\n        return Ok(vec![]);\n    }\n\n    let declaring_root = config\n        .config_files\n        .get(declaring_config)\n        .expect(\"declaring bootstrap config is loaded\")\n        .config_root();\n    let mut roots = expand_bootstrap_config_roots(&declaring_root, &patterns)?;\n    roots.sort();\n    roots.dedup();\n    if roots.is_empty() {\n        bail!(\"[bootstrap].config_roots did not match any config roots\");\n    }\n\n    let mut base = config.config_files.clone();\n    base.retain(|path, _| {\n        is_global_config(path)\n            || !path\n                .canonicalize()\n                .is_ok_and(|path| roots.iter().any(|root| path.starts_with(root)))\n    });\n    let mut maps = vec![BootstrapConfigMap {\n        config_files: base,\n        tera_ctx: config.tera_ctx.clone(),\n    }];\n    let idiomatic_filenames = BTreeMap::new();\n    for root in roots {\n        let paths = config_paths_in_dir_with_filenames(&root, &DEFAULT_CONFIG_FILENAMES);\n        let config_files = load_config_files_from_paths(&paths, &idiomatic_filenames).await?;\n        let vars_config = config.with_config_files(config_files.clone());","sourceCodeStart":1538,"sourceCodeEnd":1574,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/config/mod.rs#L1538-L1574","documentation":"A `[bootstrap]` config declares `config_roots` patterns that scope which project configs the bootstrap layer merges. After expanding those patterns from the declaring config's root, `expand_bootstrap_config_roots` matched no roots at all, so the bootstrap merge aborts instead of silently doing nothing.","triggerScenarios":"A trusted config contains `[bootstrap] config_roots = [...]` whose globs match no directories under the declaring config's root — typo, renamed directories, patterns written against the wrong root, or a worktree missing the expected layout.","commonSituations":"Bootstrap config written for a repo layout that later changed; patterns copy-pasted from another project; running from a fresh/partial clone where expected subprojects are absent.","solutions":["From the directory of the config declaring [bootstrap], verify each pattern: `ls -d <pattern>`","Update the globs to the current layout, using `**` where nesting must be matched","Remove the `[bootstrap]` block if bootstrap merging is no longer intended"],"exampleFix":"# before\n[bootstrap]\nconfig_roots = [\"svc/*\"]\n\n# after (match the actual layout)\n[bootstrap]\nconfig_roots = [\"apps/*\", \"libs/*\"]","handlingStrategy":"validation","validationCode":"cd <dir-of-bootstrap-config> && ls -d apps/* libs/* >/dev/null 2>&1 \\\n  && echo 'bootstrap config_roots match' || echo 'no match — update [bootstrap].config_roots'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat [bootstrap].config_roots like code: update globs whenever the repo layout changes","Validate patterns from the declaring config's directory, not the CWD","Add a CI step that runs a mise config command to fail fast on bootstrap misconfiguration"],"tags":["mise","bootstrap","glob","config"],"backgroundTag":"glob-pattern-no-match","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}