jdx/mise · error · eyre::Report
[monorepo].config_roots did not match any config roots
Error message
[monorepo].config_roots did not match any config roots
What it means
The `[monorepo].config_roots` glob patterns were expanded against the monorepo root directory but matched zero config roots, so mise cannot build the workspace project set. Patterns resolve relative to the project root of the config that sets `monorepo_root = true`, not the current working directory.
Source
Thrown at src/config/mod.rs:792
.ok_or_else(|| eyre!("no config file in scope sets monorepo_root = true"))?;
let monorepo_root = monorepo_config
.project_root()
.ok_or_else(|| eyre!("monorepo root config has no project root"))?;
let patterns = &monorepo_config
.monorepo()
.ok_or_else(|| eyre!("[monorepo].config_roots is required for monorepo operations"))?
.config_roots;
if patterns.is_empty() {
bail!("[monorepo].config_roots is required for monorepo operations");
}
let roots = match filenames {
Some(filenames) => {
expand_config_roots_with_filenames(&monorepo_root, patterns, None, filenames)?
}
None => expand_config_root_dirs(&monorepo_root, patterns, None)?,
};
if roots.is_empty() {
bail!("[monorepo].config_roots did not match any config roots");
}
Ok(roots)
}
pub(crate) async fn monorepo_union_tool_request_set(
self: &Arc<Self>,
) -> Result<ToolRequestSet> {
Ok(self.monorepo_union().await?.tool_request_set)
}
pub(crate) async fn monorepo_union(self: &Arc<Self>) -> Result<MonorepoUnion> {
let idiomatic_filenames = load_idiomatic_filenames().await;
let config_filenames = idiomatic_filenames
.keys()
.chain(DEFAULT_CONFIG_FILENAMES.iter())
.cloned()
.collect_vec();
let roots = self.monorepo_config_root_dirs_with_filenames(&config_filenames)?;View on GitHub (pinned to 6f52dcdf99)
Solutions
- From the directory containing monorepo_root = true, verify each glob matches: `ls -d apps/* packages/*`
- Use `**` for recursive matching (e.g. `"apps/**"`) or list each level explicitly
- Ensure matched directories actually contain a mise config file (mise.toml/.mise.toml)
- For a single root, point config_roots at the directory itself, e.g. `["apps/api"]`
Example fix
# before (no such directories under the monorepo root) [monorepo] config_roots = ["services/*"] # after [monorepo] config_roots = ["apps/*", "packages/*"]
Defensive patterns
Strategy: validation
Validate before calling
cd <monorepo-root> && ls -d apps/* packages/* >/dev/null 2>&1 \ && echo 'config_roots patterns match' || echo 'no directories matched — fix config_roots globs'
Prevention
- Globs resolve from the monorepo root, not your CWD — verify with ls -d from there
- Use ** when subdirectories nest more than one level
- Ensure matched directories contain an actual mise config file
- Re-check patterns after renaming or moving project directories
When it happens
Trigger: `config_roots = ["services/*"]` when no `services/` subdirectories exist under the monorepo root, matched directories contain no config files, patterns use the wrong base directory, or a typo/wrong case makes the glob match nothing.
Common situations: Patterns written relative to the CWD or a subproject instead of the monorepo root; repo directories renamed after patterns were added; expecting recursive matching from a single-level `*` glob; running mise from a worktree missing expected directories.
Related errors
- [monorepo].config_roots is required for monorepo operations
- [bootstrap].config_roots did not match any config roots
- Unknown shim mode
- {raw}: multiple [dotfiles] edit entries match; choose one of
- No config file found in current directory
AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22).
Data as JSON: /api/errors/0e924ee52fbc8ebb.
Report an issue: GitHub.