jdx/mise · error

conflicting managed file declarations for {} first: {

Error message

conflicting managed file declarations for {}

  first:
    {}

  second:
    {}

What it means

Thrown by merged_files_from_config when two configuration layers declare the same managed file path but with declarations that do not match (different content, mode, source, etc.). Instead of silently letting a later layer win, the tool reports both declarations verbatim via conflict_description so the user can resolve the conflict.

Source

Thrown at src/system/managed_files.rs:354

        .into_iter()
        .map(|(path, (file, base, origin))| {
            ManagedFileRequest::from_toml(config, path, file, &base, origin, secrets)
        })
        .collect()
}

fn merged_files_from_config(
    config: &Config,
) -> Result<IndexMap<PathBuf, (ManagedFileTomlConfig, PathBuf, ResourceOrigin)>> {
    let mut composed: IndexMap<PathBuf, (ManagedFileTomlConfig, PathBuf, ResourceOrigin)> =
        IndexMap::new();
    for config_files in config.bootstrap_config_maps() {
        for (path, declaration) in merged_files_from_config_files(config_files)? {
            if let Some(existing) = composed.get(&path) {
                if managed_file_declarations_match(existing, &declaration) {
                    continue;
                }
                bail!(
                    "conflicting managed file declarations for {}\n\n  first:\n    {}\n\n  second:\n    {}",
                    path.display(),
                    existing.2.conflict_description(),
                    declaration.2.conflict_description(),
                );
            }
            composed.insert(path, declaration);
        }
    }
    Ok(composed)
}

/// Returns whether sibling declarations produce the same managed file.
fn managed_file_declarations_match(
    first: &(ManagedFileTomlConfig, PathBuf, ResourceOrigin),
    second: &(ManagedFileTomlConfig, PathBuf, ResourceOrigin),
) -> bool {
    first.0 == second.0

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Compare the 'first:' and 'second:' declarations printed in the error to identify the differing field.
  2. Remove the managed-file declaration for that path from one config layer.
  3. Make the declarations identical in both layers if both must remain.
  4. If intentional override is desired, check whether the tool supports explicit layer precedence for managed files; otherwise consolidate the declaration into a single config layer.

Example fix

# before (project config)
[[bootstrap.files]]
path = "/etc/app.conf"
mode = 420
# user config also declares path = "/etc/app.conf" with mode = 438
# after
# keep the declaration only in project config, or set identical mode in both
Defensive patterns

Strategy: validation

Validate before calling

// before applying, diff declarations across config layers
const merged = {};
for (const layer of layers) {
  for (const [path, decl] of Object.entries(layer.files)) {
    if (merged[path] && JSON.stringify(merged[path]) !== JSON.stringify(decl)) {
      throw new Error(`conflicting managed file declarations for ${path}`);
    }
    merged[path] = decl;
  }
}

Prevention

When it happens

Trigger: Calling files_from_config or status_requests_from_config when bootstrap_config_maps() yields multiple config layers that each define managed file for path P with differing declaration fields.

Common situations: A project config and a user-global config both manage /etc/myapp/config.toml with different modes or content sources; environment-specific overrides changing only some fields of a managed file declaration.

Related errors


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