Weird build anomaly - dev or prod builds trying to write test .app file and failing

Some of my projects produce an error while running ‘mix compile’ that prevents successful build and deployment. I get the same error whether building using MIX_ENV=dev or MIX_ENV=prod:

** (File.Error) could not write to file “/Users/my.login/Projects/my_project/_build/test/lib/my_project/ebin/my_project.app”: no such file or directory
(elixir) lib/file.ex:934: File.write!/3
(mix) lib/mix/tasks/compile.app.ex:152: Mix.Tasks.Compile.App.run/1
(mix) lib/mix/task.ex:314: Mix.Task.run_task/3
(mix) lib/mix/tasks/compile.all.ex:63: Mix.Tasks.Compile.All.run_compiler/2
(mix) lib/mix/tasks/compile.all.ex:47: Mix.Tasks.Compile.All.do_compile/4
(mix) lib/mix/tasks/compile.all.ex:18: anonymous fn/1 in Mix.Tasks.Compile.All.run/1
(mix) lib/mix/tasks/compile.all.ex:34: Mix.Tasks.Compile.All.with_logger_app/1
(mix) lib/mix/task.ex:314: Mix.Task.run_task/3

It is looking to write the my_project.app file in the ‘_build/test’ rather than ‘_build/dev’ or ‘_build/prod’ folders. This error occurs locally on my machine as well as our CI/CD build runners. I have attempted it with several combinations of Elixir and Erlang versions all with the same result.

When I run the ‘mix compile’ command a second time without changing anything, or if I run ‘mix test’ first, the build succeeds.

This leads me to believe that the error is caused while compiling one (or more) of the dependencies but I haven’t been able to figure out which dependencies are causing the problem. Most of the dependencies are also used in other projects (same versions) which do not exhibit this behavior. I haven’t been able to identify any common denominator between projects that fail or those that do not.

Does anyone have any suggestions on how to track down the source of the problem or what to look for to identify the culprit? How does Elixir determine the path to the .app file when trying to write the file?

1 Like

I too have had this problem in most of the projects we are running. Unfortunately, I’ve only been able to do work-arounds (running it twice as you have), since I have no idea what causes it.

Hmm, my initial thought would be that a directory wasn’t able to be created, but the environment is not test yet it is trying to write to test… It happens on CI/CD so no IDE or so there to build things concurrently…

That’s confuzzling…

Need as much information about this as possible, so for each system it occurs on what is the OS, OS version, hard drive hardware, RAM, CPU, is anything running virtualized, what virtualization layer if so, what storage type if so, Elixir version, OTP version, etc… etc…

Honestly I’d start with hardware. Elixir is run on too many places in too many different ways that all work that I doubt it’s code, but it “could” be code on a specific hardware type, so need to start whittling that down. As for the *.app files, Elixir generates that for you via the Mix.Compile.App task, which is called by compile, and thus it uses the current MIX_ENV environment to determine where to write, literally joining via Path.join(path, "#{app}.app") from the same path that the beam files are written to.

I don’t suppose you could post you mix.exs file contents? How are you executing the build? What commands? Etc…?

1 Like

This ended up being a mistake of using Mix.env(:test) instead of Mix.env() == :test inside of a ubiquitous macro.

The build got into an inconsistent state since the Mix env changed partway through the compile process.

1 Like