jdx/mise · error

brew-cask: unsupported directory entry '{}'

Error message

brew-cask: unsupported directory entry '{}'

What it means

cask_directory_digest computes a content digest over a directory tree, hashing each entry kind (l for symlink, d for dir, f for file). Any entry that is none of these (socket, fifo, device) cannot be represented in the digest, so mise bails naming the offending path. Digests must be deterministic, so exotic entry types are rejected rather than skipped.

Source

Thrown at src/system/packages/brew/cask/state.rs:480

        .into_iter()
        .collect::<std::result::Result<Vec<_>, _>>()?;
    entries.sort_by(|a, b| a.path().cmp(b.path()));
    let mut digest = Sha256::new();
    for entry in entries {
        let path = entry.path();
        let relative = path.strip_prefix(root)?;
        if relative.as_os_str().is_empty() {
            continue;
        }
        let metadata = path.symlink_metadata()?;
        digest.update([if metadata.file_type().is_symlink() {
            b'l'
        } else if metadata.is_dir() {
            b'd'
        } else if metadata.is_file() {
            b'f'
        } else {
            bail!(
                "brew-cask: unsupported directory entry '{}'",
                path.display()
            );
        }]);
        hash_digest_field(&mut digest, relative.as_os_str().as_encoded_bytes());
        if metadata.file_type().is_symlink() {
            let target = std::fs::read_link(path)?;
            hash_digest_field(&mut digest, target.as_os_str().as_encoded_bytes());
        } else if metadata.is_dir() {
        } else if metadata.is_file() {
            hash_digest_field(&mut digest, hash::file_hash_sha256(path, None)?.as_bytes());
        }
    }
    Ok(hex::encode(digest.finalize()))
}

pub(super) fn hash_digest_field(digest: &mut Sha256, value: &[u8]) {
    digest.update((value.len() as u64).to_le_bytes());

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Locate the special file (`find <dir> ! -type f ! -type d ! -type l`) and remove or relocate it
  2. Quit the app that created the socket/fifo, then retry
  3. Reinstall the cask via `brew reinstall --cask <token>` to restore a clean tree

Example fix

// shell
// before: MyApp.app contains a socket from a running helper
// after:
pkill MyApp; find MyApp.app -type s -delete; mise install <cask-token>
Defensive patterns

Strategy: validation

Validate before calling

use std::os::unix::fs::FileTypeExt;
fn tree_has_special_files(root: &std::path::Path) -> std::io::Result<bool> {
    for entry in std::fs::read_dir(root)? {
        let md = entry?.metadata()?;
        let ft = md.file_type();
        if ft.is_socket() || ft.is_fifo() || ft.is_block_device() || ft.is_char_device() {
            return Ok(true);
        }
    }
    Ok(false)
}

Prevention

When it happens

Trigger: cask_directory_digest (called from CaskTargetFingerprint/cask_target_fingerprint) walks a target directory and encounters an entry whose metadata.is_file(), is_dir(), and is_symlink() are all false — e.g. a Unix socket or FIFO inside the app bundle directory being fingerprinted.

Common situations: Apps that create sockets/fifos inside their bundle or support directories; running app leaving runtime files where the fingerprint is computed; dev/tmp mounts with special files.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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