jdx/mise · error

unsupported output file type: {}

Error message

unsupported output file type: {}

What it means

write_archive packages task outputs into a zstd-compressed tar for the cache. It supports three entry types: symlinks, directories, and regular files, chosen via symlink_metadata. Anything else (on Unix: FIFOs, sockets, device files) has no tar encoding path in this code, so mise bails naming the offending relative path rather than silently dropping the output.

Source

Thrown at src/task/task_cache.rs:1601

            metadata
                .modified()
                .ok()
                .and_then(|m| m.duration_since(UNIX_EPOCH).ok())
                .map(|d| d.as_secs() as i64)
                .unwrap_or(0),
        );
        if metadata.file_type().is_symlink() {
            header.set_size(0);
            archive.append_link(&mut header, &rel, fs::read_link(&abs)?)?;
        } else if metadata.is_dir() {
            header.set_size(0);
            archive.append_data(&mut header, &rel, std::io::empty())?;
        } else if metadata.is_file() {
            header.set_size(metadata.len());
            archive.append_data(&mut header, &rel, File::open(&abs)?)?;
            restored_bytes = restored_bytes.saturating_add(metadata.len());
        } else {
            bail!("unsupported output file type: {}", rel.display());
        }
    }
    let encoder = archive.into_inner()?;
    encoder.finish()?;
    Ok(restored_bytes)
}

#[cfg(unix)]
fn metadata_mode(metadata: &fs::Metadata) -> u32 {
    use std::os::unix::fs::PermissionsExt;
    metadata.permissions().mode()
}

#[cfg(not(unix))]
fn metadata_mode(metadata: &fs::Metadata) -> u32 {
    if metadata.permissions().readonly() {
        0o444
    } else {

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Exclude the special file from outputs: narrow the glob (e.g. dist/**/*.js instead of dist/**)
  2. Delete the FIFO/socket/device file from the output dir before the task finishes, or have the tool write it elsewhere
  3. If the pipe/socket is created at runtime, configure the tool to place it outside the cached output directory

Example fix

// before (mise.toml)
[tasks.dev]
outputs = ["run/"]   # run/ contains server.sock
// after
[tasks.dev]
outputs = ["run/**/*.js"]
Defensive patterns

Strategy: validation

Validate before calling

# ensure no FIFOs/sockets/devices inside output dirs before caching
find run/ ! -type f ! -type d ! -type l -print

Try / catch

// rust: pre-scan outputs and skip/flag special files before write_archive
for entry in WalkDir::new(&abs_root) {
    let md = entry?.file_type();
    if !(md.is_file() || md.is_dir() || md.is_symlink()) {
        eprintln!("skipping non-regular output: {:?}", entry?.path());
    }
}

Prevention

When it happens

Trigger: Caching a task whose output tree contains a special file — a named pipe (mkfifo), unix socket, or device node — matched by the task's outputs patterns; encountered while iterating entries during cache save when the file_type is neither symlink, dir, nor file.

Common situations: Build tools or test runners that create sockets/FIFOs inside the output directory (e.g. dev servers leaving .sock files); test suites creating pipes under a captured outputs glob like tmp/**; a glob pattern accidentally including a runtime pipe or socket.

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@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/8b22d79cb568f5bf. Report an issue: GitHub.