Could not compile dependency :canary & module Canada.Can is not loaded and could not be found

On a project we inherited, where the original devs are not available, our mix.exs files contains:


  defp deps do
    [
# ...
      {:canary, "~> 1.1.1"},

… but Canada is not listed there.

mix.lock contains:

  "canada": {:hex, :canada, "1.0.2", "040e4c47609b0a67d5773ac1fbe5e99f840cef173d69b739beda7c98453e0770", [:mix], [], "hexpm", "4269f74153fe89583fe50bd4d5de57bfe01f31258a6b676d296f3681f1483c68"},
  "canary": {:hex, :canary, "1.1.1", "4138d5e05db8497c477e4af73902eb9ae06e49dceaa13c2dd9f0b55525ded48b", [:mix], [{:canada, "~> 1.0.1", [hex: :canada, repo: "hexpm", optional: false]}, {:ecto, ">= 1.1.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "f348d9848693c830a65b707bba9e4dfdd6434e8c356a8d4477e4535afb0d653b"},

Running mix test in CI (under Ubuntu 22 and 24) runs fine:

      - run: mix local.hex --force
      - run: mix local.rebar --force
      - run: mix deps.get
      - run: mix compile   # after fixing warnings, add --warnings-as-errors
      - run: mix test

However, when I run those step on my Mac (Intel, Sequoia 15.6.1), I get these messages at the compile step:

    error: module Canada.Can is not loaded and could not be found
    │
  2 │   import Canada.Can, only: [can?: 3]
    │   ^
    │
    └─ lib/canary/plugs.ex:2:3: Canary.Plugs (module)


== Compilation error in file lib/canary/plugs.ex ==
** (CompileError) lib/canary/plugs.ex: cannot compile module Canary.Plugs (errors have been logged)

could not compile dependency :canary, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile canary --force", update it with "mix deps.update canary" or clean it with "mix deps.clean canary"

I have not found a sequence of “mix deps.compile canary --force”, mix deps.update canary" and/or “mix deps.clean canary” which resolves this.

How should I attempt to resolve this?

1 Like

What elixir versions are used with which OTP versions?

I have the suspicion that there are subtle changes in protocol handling between the versions CI uses and the elixir version you use locally.

2 Likes

On my machine:

elixir 1.16.0-otp-25
erlang 25.3

In CI:

elixir-version: '1.16'
otp-version: '25.3'

1 Like

So Mac vs Linux is about the only difference? Or the version of OTP used to build the elixir? As 1.16 supports OTP-24, it might actually built using that.

Try 1.16.0-otp-24 locally, while sticking to OTP 25 otherwise.

1 Like

I changed .tool-versions to

elixir 1.16-otp-24
erlang 24.3

and now mix compile runs. Thanks much!

A better solution was found; now .tool-versions is

elixir 1.16-otp-25
erlang 25.3.2.20

It hadn’t been clear that erlang 25.3 didn’t mean “the latest bugfix version of 25.3"