jdx/mise · error

managed system path ' ' is declared as both a file and a…

Error message

managed system path '{}' is declared as both a file and a directory

What it means

Thrown while building managed-file status requests when a path that resolved to an unavailable (secret-backed) file declaration already exists in the set of declared managed directories. A single managed system path cannot simultaneously be a file and a directory; the config is ambiguous, so validation stops. The error names the offending path.

Solutions

  1. Decide whether the path is a file or a directory and declare it only one way across all config layers.
  2. Search all mise.toml layers for the path and remove the conflicting declaration.
  3. If the path should be a directory containing files, declare the children as files and the parent as a directory — not the same path as both.

Example fix

# before (conflict)
[bootstrap.files."/etc/app/config"]
content = "..."
[bootstrap.directories]
"/etc/app/config" = true

# after
[bootstrap.files."/etc/app/config"]
content = "..."
Defensive patterns

Strategy: validation

Validate before calling

file_paths = set(bootstrap.files)
dir_paths = set(bootstrap.directories)
overlap = file_paths & dir_paths
if overlap: raise SystemExit(f'path is both file and directory: {overlap}')

Type guard

function isExclusivePath(decls) {
  return decls.filter(d => d.kind === 'file').every(f =>
    !decls.some(d => d.kind === 'directory' && d.path === f.path));
}

Prevention

When it happens

Trigger: The same path declared once as a managed file (e.g. under bootstrap `files`) and again as a managed directory (under bootstrap `directories`), where the file's secret source was unavailable and the code checked directory states for the collision.

Common situations: Merging configs from multiple layers (user/global/project) where one layer declares the path as a file and another as a directory; refactoring a path from file to directory while leaving stale declarations elsewhere.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/87f62b4765280189. Report an issue: GitHub.

Appendix: source

Thrown at src/system/managed_files.rs:242

    let directory_states = directories
        .iter()
        .map(|directory| (directory.path.as_path(), directory.state))
        .collect::<std::collections::HashMap<_, _>>();
    for (path, (file, base, origin)) in merged_files_from_config(config)? {
        let state = file.state;
        let phase = file.phase;
        match ManagedFileRequest::from_toml(
            config,
            path.clone(),
            file,
            &base,
            origin.clone(),
            secrets,
        ) {
            Ok(file) => files.push(file),
            Err(error) if super::secrets::is_unavailable(&error) => {
                if directory_states.contains_key(path.as_path()) {
                    bail!(
                        "managed system path '{}' is declared as both a file and a directory",
                        path.display()
                    );
                }
                validate_present_ancestors(&path, state, &directory_states)?;
                unavailable.push(
                    ResourcePlan::new(
                        ResourceId::new("file", path.to_string_lossy().into_owned()),
                        "not inspected: required secret unavailable",
                        "template rendered",
                        ResourceAction::Unknown,
                    )
                    .with_origin(origin)
                    .with_file_phase(phase),
                );
            }
            Err(error) => return Err(error),
        }

View on GitHub (pinned to 533346cc37)