jdx/mise · error

brew-cask: unsupported generic artifact type

Error message

brew-cask: unsupported generic artifact type: {}

What it means

Thrown by copy_cask_artifact_at, the recursive copier used for cask `artifact` (generic) stanzas. It only knows three entry kinds: symlinks (recreated with symlinkat), directories (recreated with mkdirat and walked), and regular files (copied with openat O_EXCL then fchmod). Anything else staged at the printed path — a FIFO, unix socket, or device node — hits this bail and the install aborts.

Solutions

  1. Inspect the printed staged path with `ls -l` / `stat` to identify the non-regular entry (fifo, socket, device)
  2. Rebuild or re-download the cask payload shipping only regular files, directories, and symlinks
  3. If you control the cask, drop the special file from the archive and create it at runtime via the tool itself or a postflight step
  4. Report the cask token to its tap if the archive is upstream-broken

Example fix

# before: archive was built from a live dir and contains a socket
$ tar -cf app.tar util/            # util/run.sock included

# after: package regular files and symlinks only
$ find util \( -type f -o -type l \) | tar -cf app.tar -T -
Defensive patterns

Strategy: validation

Validate before calling

// Before installing, walk the staged artifact tree and reject non-regular entries.
fn staged_tree_is_copyable(root: &std::path::Path) -> std::io::Result<()> {
    let meta = root.symlink_metadata()?;
    let ft = meta.file_type();
    if ft.is_symlink() || ft.is_file() {
        return Ok(());
    }
    if !ft.is_dir() {
        return Err(std::io::Error::new(std::io::ErrorKind::InvalidInput,
            format!("unsupported artifact type: {}", root.display())));
    }
    for entry in std::fs::read_dir(root)? {
        staged_tree_is_copyable(&entry?.path())?;
    }
    Ok(())
}

Type guard

fn is_supported_artifact_entry(ft: &std::fs::FileType) -> bool {
    ft.is_file() || ft.is_dir() || ft.is_symlink()
}

Prevention

When it happens

Trigger: Installing a cask whose downloaded/staged archive contains a special file (mkfifo-created entry, socket, device node) anywhere in the artifact tree that copy_cask_artifact recurses into; reachable whenever the generic artifact source is copied into the target parent.

Common situations: Hand-built or repackaged cask archives that tar'd up a live directory containing sockets/fifos; archives produced on Linux with mknod entries; casks that worked under Homebrew's ruby installer because ruby's FileUtils skipped such entries silently.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/220d94ab974e32b5. Report an issue: GitHub.

Appendix: source

Thrown at src/system/packages/brew/cask.rs:2090

            copy_cask_artifact_at(&entry.path(), &fd, &entry.file_name())?;
        }
        nix::sys::stat::fchmod(&fd, mode)?;
    } else if metadata.is_file() {
        let destination = nix::fcntl::openat(
            parent,
            name,
            nix::fcntl::OFlag::O_WRONLY
                | nix::fcntl::OFlag::O_CREAT
                | nix::fcntl::OFlag::O_EXCL
                | nix::fcntl::OFlag::O_NOFOLLOW,
            nix::sys::stat::Mode::S_IRUSR | nix::sys::stat::Mode::S_IWUSR,
        )?;
        let mut source = std::fs::File::open(from)?;
        let mut destination = std::fs::File::from(destination);
        copy_file_contents(&mut source, &mut destination)?;
        nix::sys::stat::fchmod(&destination, mode)?;
    } else {
        bail!(
            "brew-cask: unsupported generic artifact type: {}",
            from.display()
        );
    }
    Ok(())
}

#[cfg(all(unix, target_os = "macos"))]
fn copy_file_contents(from: &mut std::fs::File, to: &mut std::fs::File) -> Result<()> {
    use std::os::fd::AsRawFd;

    // SAFETY: both descriptors remain open for the call and fcopyfile does not
    // retain them. A null state requests the default copyfile state.
    let result = unsafe {
        nix::libc::fcopyfile(
            from.as_raw_fd(),
            to.as_raw_fd(),
            std::ptr::null_mut(),

View on GitHub (pinned to 6f52dcdf99)