jdx/mise · error
[monorepo].config_roots is required for monorepo operations
Error message
[monorepo].config_roots is required for monorepo operations
What it means
A monorepo operation (lockfile resolution or config-root discovery) ran but the monorepo config has no [monorepo].config_roots set, or it is set to an empty array. mise requires this key to know which subdirectories contain mise configs.
Solutions
- Add [monorepo] config_roots to the monorepo root mise.toml, e.g. config_roots = ["apps/*", "packages/*"]
- If templating produced an empty list, fix the template/condition so at least one pattern remains
- If you do not intend monorepo features, remove the [monorepo] table so normal config loading is used
Example fix
// before [monorepo] type = " Nx" // after [monorepo] type = "nx" config_roots = ["apps/*", "packages/*"]
Defensive patterns
Strategy: validation
Validate before calling
# shell pre-check before running mise monorepo commands grep -q '^config_roots' mise.toml || echo "[monorepo].config_roots is missing" # or in Rust, parse the config and check: let patterns = cfg.monorepo.config_roots.as_ref(); let ok = matches!(patterns, Some(p) if !p.is_empty());
Type guard
// Rust
fn has_config_roots(cfg: &MonorepoConfig) -> bool {
cfg.config_roots.as_ref().map_or(false, |p| !p.is_empty())
} Try / catch
// Rust
match config.monorepo_config_root_dirs() {
Ok(roots) => use(roots),
Err(e) if e.to_string().contains("config_roots is required") => {
bail!("add [monorepo].config_roots to the monorepo root mise.toml");
}
Err(e) => return Err(e),
} Prevention
- Always define config_roots together with any [monorepo] table
- Include a schema/lint check of mise.toml in CI to catch missing keys
- Avoid empty-list templating for config_roots
When it happens
Trigger: Calling monorepo_config_root_dirs (directly or via monorepo_lockfile_root, monorepo_config_root_dirs_for_lockfiles, monorepo_config_root_dirs_with_filenames) when monorepo.config.config_roots is None, or explicitly when it is an empty list.
Common situations: A monorepo root mise.toml declares [monorepo] metadata but omits config_roots; or config_roots was emptied by templating/environment so monorepo features (lockfiles, workspace tasks) cannot resolve.
Understand the failure class
Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.
Related errors
- backend must be a string or table
- Cannot use :task syntax without a monorepo root
- collection updates require scalar or array values
- command wrapper for must have a non-blank command
- config set requires a TOML config file, but
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/192c815295e025d2.
Report an issue: GitHub.
Appendix: source
Thrown at src/config/mod.rs:879
/// Resolve `[monorepo].config_roots`.
///
/// `None` matches any existing directory and is used for lockfile migration
/// and routing. `Some(filenames)` requires a recognized config or idiomatic
/// version file and is used for full monorepo union/task loading.
pub(crate) fn monorepo_config_root_dirs(
&self,
filenames: Option<&[String]>,
) -> Result<Vec<PathBuf>> {
let monorepo_config = find_monorepo_config(&self.config_files)
.ok_or_else(|| eyre!("no config file in scope sets monorepo_root = true"))?;
let monorepo_root = monorepo_config.root;
let patterns = monorepo_config
.monorepo
.config_roots
.ok_or_else(|| eyre!("[monorepo].config_roots is required for monorepo operations"))?;
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)
}View on GitHub (pinned to 533346cc37)