jdx/mise · error · eyre::Report

unsupported host path type: {}

Error message

unsupported host path type: {}

What it means

build_layer_from_path classifies the source by its file type (via symlink_metadata, so symlinks are detected as such). Only regular files, symlinks, and directories are supported; anything else — FIFO, unix socket, block/char device — hits this guard. The tar layer has no meaningful, portable representation for those types.

Source

Thrown at src/oci/layer.rs:141

        eyre::bail!("cannot copy a file or symlink to the image root");
    }
    if image_path.ends_with('/') {
        eyre::bail!(
            "copy image path {image_path:?} ends with `/` but {} is not a directory; \
             specify the exact destination file name",
            host_path.display()
        );
    }

    let kind = if metadata.file_type().is_symlink() {
        EntryKind::Symlink(
            std::fs::read_link(host_path)
                .wrap_err_with(|| format!("reading symlink {}", host_path.display()))?,
        )
    } else if metadata.is_file() {
        EntryKind::File
    } else {
        eyre::bail!("unsupported host path type: {}", host_path.display());
    };
    let mode = match &kind {
        EntryKind::Symlink(_) => 0o777,
        EntryKind::File if file_is_executable(host_path, &metadata) => 0o755,
        EntryKind::File => 0o644,
        EntryKind::Dir => unreachable!(),
    };
    let target_path = Path::new(target);
    let rel = target_path
        .file_name()
        .map(PathBuf::from)
        .ok_or_else(|| eyre::eyre!("copy image path has no file name: {image_path}"))?;
    let prefix = target_path
        .parent()
        .unwrap_or_else(|| Path::new(""))
        .to_string_lossy();
    let size = if matches!(kind, EntryKind::Symlink(_)) {
        0

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Point the entry at the real file or directory you intended, not the socket/fifo.
  2. Exclude runtime artifacts (sockets, fifos) from the source set before building.
  3. If you need a socket in the image, create it at container start (entrypoint), not by copying from the host.

Example fix

# before
files = [ "/var/run/docker.sock:/run/docker.sock" ]

# after
# do not copy sockets; create at runtime, e.g. via entrypoint
files = [ "./run-wrapper.sh:/usr/local/bin/run-wrapper.sh" ]
Defensive patterns

Strategy: validation

Validate before calling

import os, stat, sys
for src, _ in copy_entries.items():
    m = os.lstat(src).st_mode
    kind = stat.S_IFMT(m)
    if kind not in (stat.S_IFREG, stat.S_IFLNK, stat.S_IFDIR):
        sys.exit(f"unsupported source type (fifo/socket/device): {src}")

Type guard

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

Prevention

When it happens

Trigger: A copy entry whose source is a named pipe (mkfifo), a listening unix socket file (e.g. /var/run/docker.sock on hosts where it's a socket rather than a symlink), or a device node.

Common situations: Broad globbing over a directory that happens to include runtime sockets/pipes; copying /var/run or /tmp contents into an image; leftover fifo artifacts in a dotfiles repo.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/5af828070b8db6af. Report an issue: GitHub.