cross-rs/cross · warning

source is pointing to a directory instead of its contents

Error message

source is pointing to a directory instead of its contents: {} -> {}
This might be a bug. {}

What it means

During remote builds, copy_files copies paths into the data volume. When a source path resolves to a directory but the destination expects its contents (the relative path equals the directory's file name and does not end in `/.`), cross warns that the caller probably pointed at the directory itself rather than its children — flagged as a possible bug in cross's own copy logic.

Solutions

  1. Update cross to the latest version; this message explicitly hints at an internal bug that may already be fixed.
  2. Check which path is being copied (the message prints src -> dst) and ensure the source points at the contents (e.g. append `/.`) if you control the copy.
  3. If the paths are cross-managed (cargo/rust directories), clear stale directories (e.g. the cross home/cache) so they are recreated with the expected layout.
  4. File an issue with cross including the printed source/destination and panic Location if it persists.

Example fix

// before
let src = Path::new("/home/user/.cargo/registry");
copy_files(src, dst)?;

// after — point at contents when a directory copy is intended
let src = Path::new("/home/user/.cargo/registry/.");
copy_files(src, dst)?;
Defensive patterns

Strategy: fallback

Validate before calling

// Detect suspicious directory-source copies before invoking cross remote builds
use std::fs;
if fs::metadata(src)?.is_dir() && !src.ends_with("/.") {
    eprintln!("copy source {} is a directory; cross may warn", src.display());
}

Try / catch

// Treat as non-fatal warning; escalate only if the remote build then fails
if let Err(e) = run_cross_remote() {
    if String::from_utf8_lossy(&e.stderr).contains("pointing to a directory instead of its contents") {
        update_cross_and_retry()?;
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: Calling copy_files (directly or via copy_files_nocache, copy_file_list, copy_cargo, copy_rust_base, copy_rust_manifest, copy_rust_triple) with a src directory whose destination relationship makes rel == src.file_name(), i.e. contents land one level deeper than intended.

Common situations: Remote builds where the cargo home/toolchain directories layout changed between cross versions; symlinks or bind-mount layouts causing a directory to appear as a copy source; genuine cross bugs filed upstream.

Understand the failure class

Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.

Related errors


AI-assisted analysis of cross-rs/cross@8c1a8aa4b6 (2026-09-13). Data as JSON: /api/errors/ad80433eca8bc240. Report an issue: GitHub.

Appendix: source

Thrown at src/docker/remote.rs:87

    /// copy the contents from `src` into `dst`, `src` must end with `/.`
    #[track_caller]
    fn copy_files(
        &self,
        src: &Path,
        reldst: &str,
        mount_prefix: &str,
        msg_info: &mut MessageInfo,
    ) -> Result<ExitStatus> {
        if let Some((_, rel)) = reldst.rsplit_once('/') {
            if msg_info.cross_debug
                && src.is_dir()
                && !src.to_string_lossy().ends_with("/.")
                && rel
                    == src
                        .file_name()
                        .expect("filename should be defined as we are a directory")
            {
                msg_info.warn(format_args!(
                    "source is pointing to a directory instead of its contents: {} -> {}\nThis might be a bug. {}",
                    src.as_posix_relative()?,
                    reldst,
                    std::panic::Location::caller()
                ))?;
            }
        }
        subcommand_or_exit(self.engine, "cp")?
            .arg("-a")
            .arg(src.to_utf8()?)
            .arg(format!("{}:{mount_prefix}/{reldst}", self.container))
            .run_and_get_status(msg_info, false)
    }

    /// copy files for a docker volume, does not include cache directories
    ///
    /// ## Note
    ///

View on GitHub (pinned to 8c1a8aa4b6)