{"record":{"id":"192c815295e025d2","repo":"jdx/mise","slug":"monorepo-config-roots-is-required-for-monorepo-o","errorCode":null,"errorMessage":"[monorepo].config_roots is required for monorepo operations","messagePattern":"\\[monorepo\\]\\.config_roots is required for monorepo operations","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/config/mod.rs","lineNumber":879,"sourceCode":"\n    /// Resolve `[monorepo].config_roots`.\n    ///\n    /// `None` matches any existing directory and is used for lockfile migration\n    /// and routing. `Some(filenames)` requires a recognized config or idiomatic\n    /// version file and is used for full monorepo union/task loading.\n    pub(crate) fn monorepo_config_root_dirs(\n        &self,\n        filenames: Option<&[String]>,\n    ) -> 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    }","sourceCodeStart":861,"sourceCodeEnd":897,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/config/mod.rs#L861-L897","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\n[monorepo]\ntype = \" Nx\"\n// after\n[monorepo]\ntype = \"nx\"\nconfig_roots = [\"apps/*\", \"packages/*\"]","handlingStrategy":"validation","validationCode":"# shell pre-check before running mise monorepo commands\ngrep -q '^config_roots' mise.toml || echo \"[monorepo].config_roots is missing\"\n# or in Rust, parse the config and check:\nlet patterns = cfg.monorepo.config_roots.as_ref();\nlet ok = matches!(patterns, Some(p) if !p.is_empty());","typeGuard":"// Rust\nfn has_config_roots(cfg: &MonorepoConfig) -> bool {\n    cfg.config_roots.as_ref().map_or(false, |p| !p.is_empty())\n}","tryCatchPattern":"// Rust\nmatch config.monorepo_config_root_dirs() {\n    Ok(roots) => use(roots),\n    Err(e) if e.to_string().contains(\"config_roots is required\") => {\n        bail!(\"add [monorepo].config_roots to the monorepo root mise.toml\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["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"],"tags":["config","monorepo","toml"],"backgroundTag":"missing-required-config-field","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"}