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

  1. From the directory containing monorepo_root = true, verify each glob matches: `ls -d apps/* packages/*`
  2. Use `**` for recursive matching (e.g. `"apps/**"`) or list each level explicitly
  3. Ensure matched directories actually contain a mise config file (mise.toml/.mise.toml)
  4. 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

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


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/0e924ee52fbc8ebb. Report an issue: GitHub.