{"record":{"id":"0e924ee52fbc8ebb","repo":"jdx/mise","slug":"monorepo-config-roots-did-not-match-any-config-r","errorCode":null,"errorMessage":"[monorepo].config_roots did not match any config roots","messagePattern":"\\[monorepo\\]\\.config_roots did not match any config roots","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config/mod.rs","lineNumber":888,"sourceCode":"    ) -> Result<Vec<PathBuf>> {\n        let monorepo_config = find_monorepo_config(&self.config_files)\n            .ok_or_else(|| eyre!(\"no config file in scope sets monorepo_root = true\"))?;\n        let monorepo_root = monorepo_config.root;\n        let patterns = monorepo_config\n            .monorepo\n            .config_roots\n            .ok_or_else(|| eyre!(\"[monorepo].config_roots is required for monorepo operations\"))?;\n        if patterns.is_empty() {\n            bail!(\"[monorepo].config_roots is required for monorepo operations\");\n        }\n        let roots = match filenames {\n            Some(filenames) => {\n                expand_config_roots_with_filenames(&monorepo_root, &patterns, None, filenames)?\n            }\n            None => expand_config_root_dirs(&monorepo_root, &patterns, None)?,\n        };\n        if roots.is_empty() {\n            bail!(\"[monorepo].config_roots did not match any config roots\");\n        }\n        Ok(roots)\n    }\n\n    pub(crate) async fn monorepo_union_tool_request_set(\n        self: &Arc<Self>,\n    ) -> Result<ToolRequestSet> {\n        Ok(self.monorepo_union().await?.tool_request_set)\n    }\n\n    /// Loads the union plus the monorepo root directory's own effective\n    /// requests, for lockfile maintenance of the shared root lockfile.\n    ///\n    /// `monorepo_union` merges the root's configs underneath each declared\n    /// config root, so a sibling's request for a short shadows the monorepo\n    /// root's own request for it. Treating the union as the set of live\n    /// requests for the root lockfile would then drop the root's request:\n    /// `mise lock --upgrade` migrated a v0 monorepo lockfile without binding","sourceCodeStart":870,"sourceCodeEnd":906,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/config/mod.rs#L870-L906","documentation":"Monorepo config resolution matched zero directories for the glob patterns in [monorepo].config_roots. The patterns exist and are non-empty, but nothing on disk matches them, so mise cannot enumerate per-project config roots and aborts the monorepo operation.","triggerScenarios":"Calling monorepo_config_root_dirs (or its callers: monorepo_lockfile_root, monorepo_config_root_dirs_for_lockfiles, monorepo_config_root_dirs_with_filenames) when expand_config_root_dirs / expand_config_roots_with_filenames returns an empty vec — patterns match no existing subdirectories with configs.","commonSituations":"Typo'd or stale glob patterns (e.g. \"packages/*\" after restructuring to \"libs/*\"), patterns relative to the wrong monorepo root, or subdirectories present but containing no mise.toml/.mise.toml config.","solutions":["Verify the glob patterns in [monorepo].config_roots match directories that actually contain mise config files","Run from the actual monorepo root (patterns are expanded relative to monorepo_config.root)","Check for typos or renamed directories and update the patterns","Run with MISE_DEBUG=1 to see which roots were scanned"],"exampleFix":"// before\n[monorepo]\nconfig_roots = [\"packages/*\"]\n// after (repo restructured)\n[monorepo]\nconfig_roots = [\"libs/*\", \"apps/*\"]","handlingStrategy":"validation","validationCode":"# verify each config_root pattern matches at least one dir with a mise config\nfor pat in $(yq '.monorepo.config_roots[]' mise.toml); do\n  ls -d $pat >/dev/null 2>&1 || echo \"pattern $pat matches nothing\"\ndone","typeGuard":"// Rust\nfn patterns_match_any(root: &Path, patterns: &[String]) -> bool {\n    patterns.iter().any(|p| glob_dir(root, p).next().is_some())\n}","tryCatchPattern":"// Rust\nmatch config.monorepo_config_root_dirs() {\n    Ok(roots) => use(roots),\n    Err(e) if e.to_string().contains(\"did not match any config roots\") => {\n        eprintln!(\"fix [monorepo].config_roots globs — no matches under monorepo root\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Keep config_roots patterns in sync with directory renames/restructures","Verify patterns resolve relative to the monorepo root, not the cwd","Test patterns with ls/glob before committing them"],"tags":["config","monorepo","glob","no-match"],"backgroundTag":"empty-result-set","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}