jdx/mise · error

brew-cask: unsupported target type '{}'

Error message

brew-cask: unsupported target type '{}'

What it means

cask_target_fingerprint fingerprints an artifact target as either a directory or a file so cask ownership can be verified. The SOURCE shows a dir/file check, and any target whose type is neither (e.g. a dangling symlink, socket, fifo, or device node) cannot be fingerprinted, so mise bails naming the path. This keeps ownership digests well-defined.

Source

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

        let target = std::fs::read_link(path)?;
        return Ok(CaskTargetFingerprint {
            kind: CaskTargetKind::Symlink,
            digest: hex::encode(Sha256::digest(target.as_os_str().as_encoded_bytes())),
        });
    }
    if metadata.is_file() {
        return Ok(CaskTargetFingerprint {
            kind: CaskTargetKind::File,
            digest: hash::file_hash_sha256(path, None)?,
        });
    }
    if metadata.is_dir() {
        return Ok(CaskTargetFingerprint {
            kind: CaskTargetKind::Directory,
            digest: cask_directory_digest(path)?,
        });
    }
    bail!("brew-cask: unsupported target type '{}'", path.display())
}

/// Content identity intentionally excludes timestamps, ownership, and modes.
/// It hashes stable relative paths, entry kinds, file bytes, and link targets
/// without following symlinks.
pub(super) fn cask_directory_digest(root: &Path) -> Result<String> {
    let mut entries = WalkDir::new(root)
        .follow_links(false)
        .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;
        }

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Inspect the reported path (`ls -la <path>`) and remove or replace the non-file/non-directory entry (e.g. delete the dangling symlink)
  2. Run `brew reinstall --cask <token>` to restore a clean target layout
  3. Retry the mise cask operation after the target is a normal file or directory

Example fix

// shell
// before: /Applications/MyApp is a broken symlink
// after:
rm /Applications/MyApp && mise reinstall <cask-token>
Defensive patterns

Strategy: validation

Validate before calling

fn fingerprintable(p: &std::path::Path) -> bool {
    match std::fs::symlink_metadata(p) {
        Ok(m) => m.is_dir() || m.is_file(),
        Err(_) => false,
    }
}

Prevention

When it happens

Trigger: cask_target_fingerprint is called (from install_app, validate_adoptable_apps, CaskTargetRecord, cask_target_record_matches, staged_target_matches) on a path whose metadata is not a directory and not a regular file — e.g. a broken symlink at the target location.

Common situations: A previous tool left a dangling symlink where an app/binary should live; dev filesystems with sockets or fifos in target locations; corrupted installs.

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/4647e7cb1eb00184. Report an issue: GitHub.