jdx/mise · error

brew-cask: unsupported directory entry

Error message

brew-cask: unsupported directory entry '{}'

What it means

While hashing a cask directory's contents for its content digest, cask_directory_digest classifies each entry as symlink, directory, or file. Any other entry kind (socket, fifo, device node) has no stable content identity, so the digest computation aborts with this error.

Solutions

  1. Find the special entry (`find <dir> ! -type f ! -type d ! -type l`) and remove it.
  2. Stop the process creating the socket/fifo inside the cask directory, then retry.
  3. Reinstall the cask to restore a clean artifact tree.

Example fix

// before: daemon socket inside app dir
$ find /Applications/MyApp.app ! -type f ! -type d ! -type l
/Applications/MyApp.app/Contents/daemon.sock

// after: stop daemon, remove socket, retry the mise operation
Defensive patterns

Strategy: validation

Validate before calling

let bad: Vec<_> = walk(dir).filter(|p| {
    let ft = std::fs::symlink_metadata(p).unwrap().file_type();
    !(ft.is_file() || ft.is_dir() || ft.is_symlink())
}).collect();
if !bad.is_empty() { /* stop daemons and remove special entries first */ }

Type guard

fn digestable_entry(p: &Path) -> bool {
    matches!(std::fs::symlink_metadata(p).map(|m| m.file_type()), Ok(ft)
        if ft.is_file() || ft.is_dir() || ft.is_symlink())
}

Try / catch

match result {
    Err(e) if e.to_string().contains("unsupported directory entry") => {
        let dir = extract_dir(&e);
        find_and_remove_special_entries(dir)?; retry()
    }
    r => r,
}

Prevention

When it happens

Trigger: cask_directory_digest (called from CaskTargetFingerprint) iterates a directory tree and encounters an entry whose file type is none of symlink/dir/file.

Common situations: An app bundle or support directory contains a Unix domain socket or named pipe left by a running daemon; dev-mode tooling created special files inside an application directory.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: 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 533346cc37)