Skip to content

File.cp_r!/2 (and I'm assuming File.cp_r/2) reports the source as the missing when the destination is missing #14924

@fozcodes

Description

@fozcodes

Elixir and Erlang/OTP versions

Version:

Erlang/OTP 28 [erts-16.1.1] [source] [64-bit] [smp:10:10] [ds:10:10:10] [async-threads:1] [jit]

Elixir 1.19.3 (compiled with Erlang/OTP 28)

(also saw this in 1.18.4 too)

Operating system

MacOS, Linux

Current behavior

I discovered this while trying to use Griffin to build a static site. In my Github actions, it was complaining about some assets/* it was trying to copy into _site/assets during build.

Here's a minimal example:

codeguy on  main [!?] via 💧 v1.19.3 (OTP 28)
λ touch ignore/test_file.txt
codeguy on  main [!?] via 💧 v1.19.3 (OTP 28)
λ la ignore/
drwxr-xr-x foz staff  96 B Tue Nov 18 20:34:10 2025  .
drwxr-xr-x foz staff 768 B Tue Nov 18 20:34:01 2025  ..
.rw-r--r-- foz staff   0 B Tue Nov 18 20:34:10 2025  test_file.txt
codeguy on  main [!?] via 💧 v1.19.3 (OTP 28)
λ elixir -e 'File.cp_r!("ignore/test_file.txt", "some_non_existent_dir/test_file.txt")'
** (File.CopyError) could not copy recursively from "ignore/test_file.txt" to "some_non_existent_dir/test_file.txt". ignore/test_file.txt: no such file or directory
    (elixir 1.19.3) lib/file.ex:1215: File.cp_r!/3
    nofile:1: (file)
    (stdlib 7.1) erl_eval.erl:924: :erl_eval.do_apply/7
    (elixir 1.19.3) lib/code.ex:629: Code.validated_eval_string/3

As you can see it errors saying that the source doesn't exist, but it's the destination that's the issue.

Confusing, until you figure out what's happening.

I was gonna make a PR, but I'm having trouble tracking down where it comes from. This might ultimately come from :file.copy in Erlang/OTP? https://github.com/elixir-lang/elixir/blob/main/lib/elixir/lib/file.ex#L1280

If it is Erlang, and someone can point me in the right direction in the erlang repo, I'd be happy to take a crack at a fix.

Or we could always catch the erlang error and double-check its math 😄

Thanks!

Expected behavior

  1. When the source doesn't exist, the error reports "no such file or directory" on the source
  2. When the destination doesn't exist, the error reports "no such file or directory" on the destination

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions