jdx/mise · error
config index exists
Error message
config index exists
What it means
mise panics with 'config index exists' in the bootstrap config sibling-insertion logic when `config_files.get_index(*index)` returns `None` for an index taken from `sibling_indices`. Those indices are recorded while iterating the same IndexMap, so they must remain valid; the panic means the map shrank or was rebuilt between recording the indices and using them for precedence-based insertion (`shift_insert` of a bootstrap config file).
Source
Thrown at src/config/mod.rs:1668
config_files.insert(path, config_file);
return;
}
let precedence = bootstrap_config_filename_precedence(&path);
let sibling_indices = config_files
.keys()
.enumerate()
.filter(|(_, existing)| existing.parent() == path.parent())
.map(|(index, _)| index)
.collect_vec();
let index = sibling_indices
.iter()
.copied()
.find(|index| {
bootstrap_config_filename_precedence(
config_files
.get_index(*index)
.expect("config index exists")
.0,
) < precedence
})
.or_else(|| sibling_indices.last().map(|index| index + 1))
.unwrap_or(config_files.len());
config_files.shift_insert(index, path, config_file);
}
fn bootstrap_config_filename_precedence(path: &Path) -> Option<usize> {
DEFAULT_CONFIG_FILENAMES.iter().position(|candidate| {
!is_glob_pattern(candidate) && Path::new(candidate).file_name() == path.file_name()
})
}
fn configs_at_root<'a>(dir: &Path, config_files: &'a ConfigMap) -> Vec<&'a Arc<dyn ConfigFile>> {
// Highest precedence config files are returned first.
let mut configs: Vec<&'a Arc<dyn ConfigFile>> = DEFAULT_CONFIG_FILENAMES
.iter()View on GitHub (pinned to afd2eddd3a)
Solutions
- Recompute sibling indices immediately before the precedence lookup instead of caching them across mutations
- Verify no code path removes entries from `config_files` between index collection and `shift_insert`
- Add a bounds check and skip stale indices rather than panicking
- Reproduce with the layered config set that triggers sibling dedup to identify which mutation drops the entry
Example fix
// before
.find(|index| config_files.get_index(*index).expect("config index exists").0)
// after
.find(|index| config_files.get_index(*index).map(|(k, _)| k).is_some_and(|k| bootstrap_config_filename_precedence(k) < precedence)) Defensive patterns
Strategy: validation
Validate before calling
if config_files.get_index(i).is_none() { continue; } // skip stale sibling index Type guard
fn valid_index(map: &ConfigFiles, i: usize) -> bool { i < map.len() } Prevention
- Recompute indices immediately before use rather than caching them
- Avoid mutating the IndexMap between index collection and shift_insert
- Check the map length before dereferencing cached indices
When it happens
Trigger: Running the bootstrap config-file ordering code when `config_files` is mutated (entries removed/merged) between collecting `sibling_indices` and the precedence `find` that dereferences them — e.g. layered config loading removes a file, or the index list was computed against a different map instance.
Common situations: Bootstrap `[config]` declarations referencing sibling config files that get deduplicated or dropped during layered load; env-specific config filtering shrinking the map mid-pass; refactors that reorder collection of sibling indices.
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
- inline content
- declaring bootstrap config is loaded
- enabled accounts were prepared
- configured notifications came from managed files
- configured notifications prepared services
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/e9b3baa36ef7bbe5.
Report an issue: GitHub.