jdx/mise · error

declaring bootstrap config is loaded

Error message

declaring bootstrap config is loaded

What it means

mise panics with 'declaring bootstrap config is loaded' when `config.config_files.get(declaring_config)` returns `None` while expanding `[bootstrap].config_roots` patterns. The `declaring_config` index is expected to point at a config file that was loaded into the current config's `config_files` map; if the declaring file was not loaded (skipped include, filtered env, different config root), the lookup panics.

Source

Thrown at src/config/mod.rs:1757

        .find(|cf| cf.monorepo_root() == Some(true))
}

/// Loads each selected bootstrap root as an independent hierarchy with scoped variables.
async fn load_bootstrap_config_maps(config: &Config) -> Result<Vec<BootstrapConfigMap>> {
    let Some((declaring_config, patterns)) = config.config_files.iter().find_map(|(path, cf)| {
        cf.bootstrap_config()
            .and_then(|bootstrap| bootstrap.config_roots.map(|patterns| (path, patterns)))
    }) else {
        return Ok(vec![]);
    };
    if patterns.is_empty() {
        return Ok(vec![]);
    }

    let declaring_root = config
        .config_files
        .get(declaring_config)
        .expect("declaring bootstrap config is loaded")
        .config_root();
    let mut roots = expand_bootstrap_config_roots(&declaring_root, &patterns)?;
    roots.sort();
    roots.dedup();
    if roots.is_empty() {
        bail!("[bootstrap].config_roots did not match any config roots");
    }

    let mut base = config.config_files.clone();
    base.retain(|path, _| {
        is_global_config(path)
            || !path
                .canonicalize()
                .is_ok_and(|path| roots.iter().any(|root| path.starts_with(root)))
    });
    let mut maps = vec![BootstrapConfigMap {
        config_files: base,
        tera_ctx: config.tera_ctx.clone(),

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Ensure the config instance passed to the roots-expansion code actually contains the declaring file in `config_files`
  2. Check that the file declaring `[bootstrap].config_roots` is loaded (correct include path, active env, trusted)
  3. Return a descriptive error instead of panicking when the declaring config is absent
  4. Reproduce with the mise.toml layout whose bootstrap declaration triggers the missing lookup

Example fix

// before
let declaring_root = config.config_files.get(declaring_config)
    .expect("declaring bootstrap config is loaded").config_root();
// after
let declaring_root = config.config_files.get(declaring_config)
    .with_context(|| format!("declaring bootstrap config {declaring_config:?} not loaded"))?
    .config_root();
Defensive patterns

Strategy: validation

Validate before calling

if !config.config_files.contains_key(declaring_config) { bail!("declaring bootstrap config not loaded"); }

Type guard

config.config_files.get(declaring_config).is_some()

Prevention

When it happens

Trigger: A config file declares `[bootstrap].config_roots` but is not present in `config.config_files` when the roots are expanded — e.g. the declaring file is only reachable via an include that was not loaded, the declaration is resolved against a different config instance than the one that loaded it, or layered loading dropped the file.

Common situations: Users declare bootstrap config roots in a file included conditionally or in an env-specific config not active; referencing a declaring config from a stale index after config reload; refactors that pass the wrong config instance into the roots-expansion helper.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/3a039ae706e6db3c. Report an issue: GitHub.