jdx/mise · critical

refusing to resolve managed directory {} to the filesystem r

Error message

refusing to resolve managed directory {} to the filesystem root

What it means

When a symlink in the managed path is followed, the library re-resolves the remaining path and refuses if the result is the filesystem root `/`. Resolving a managed directory to `/` would make the library operate on the root directory, which is never intended and extremely destructive. This is a hard safety invariant in the symlink-following logic.

Source

Thrown at src/system/managed_files.rs:1626

                    SFlag::from_bits_truncate(metadata.st_mode).contains(SFlag::S_IFLNK)
                }) {
                    let parent = fstat(&directory)?;
                    if parent.st_uid != 0 || parent.st_mode & 0o022 != 0 {
                        bail!(
                            "refusing to follow symlink {} from an untrusted parent directory",
                            component_path.display()
                        );
                    }
                    let target = nix::fcntl::readlinkat(&directory, name.as_os_str())?;
                    let mut resolved = if Path::new(&target).is_absolute() {
                        PathBuf::from(target)
                    } else {
                        current.join(target)
                    };
                    resolved.extend(components.iter().skip(index + 1));
                    let resolved = resolved.absolutize()?.to_path_buf();
                    if resolved == Path::new("/") {
                        bail!(
                            "refusing to resolve managed directory {} to the filesystem root",
                            path.display()
                        );
                    }
                    return open_or_create_directory_tree_inner(&resolved, followed_symlinks + 1);
                }
                if open_error != nix::errno::Errno::ENOENT {
                    return Err(open_error).wrap_err_with(|| {
                        format!(
                            "failed to open path component {} without following symlinks",
                            component_path.display()
                        )
                    });
                }
                let created_by_us = match mkdirat(
                    &directory,
                    name.as_os_str(),
                    Mode::from_bits_truncate(0o777),

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Remove or fix the symlink that resolves to `/` (`readlink -f <symlink>` to confirm)
  2. Point the symlink at a specific subdirectory rather than the root
  3. Recreate the managed directory structure from a clean state
  4. Audit symlink chains with `namei -l <path>` before relinking

Example fix

// before
$ ln -s / /opt/tools/root
// after
$ rm /opt/tools/root
$ ln -s /opt/tools-v1 /opt/tools/root
Defensive patterns

Strategy: validation

Validate before calling

fn resolves_to_root(path: &Path) -> std::io::Result<bool> {
    let resolved = path.canonicalize()?;
    Ok(resolved == std::path::Path::new("/"))
}

Type guard

fn not_root(path: &Path) -> bool {
    std::fs::canonicalize(path).map(|p| p != std::path::Path::new("/")).unwrap_or(true)
}

Try / catch

match result {
    Err(e) if e.to_string().contains("to the filesystem root") => {
        let target = std::fs::read_link(suspect_link(path))?;
        remove_and_relink(target); // never point at /
    }
    Err(e) => return Err(e),
    Ok(v) => v,
}

Prevention

When it happens

Trigger: A symlink component whose target (after absolutize and appending remaining components) equals `/` — e.g. a symlink `tools -> /` or a chain of symlinks that ultimately resolves to `/`.

Common situations: A malicious or mistaken symlink pointing at `/`; careless link farms where a symlink chain (link -> link2 -> /) collapses to the root; cleanup scripts that repointed symlinks incorrectly.

Understand the failure class

Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.

Related errors


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