** (RuntimeError) Application.compile_env/3 cannot be called inside functions, only in the module body

Original error:

$ mix credo --all

┃ [W] ↗ Module attribute @minimum makes use of unsafe Application configuration call Application.get_env/2
┃       lib/Foo.ex:4 #(Foo)

Attempted solution:

defmodule Foo do

  @minimum Application.compile_env(:the_app, :minimum)

  def compute_minimum(%{
        rate: {:error, :no_rate_found},
        price: price,
        amount: amount
      }) do
    reversed_symbol_rate_lookup_results =
      Bar.lookup_rate(
        price,
        amount
      )

    Decimal.mult(@minimum, reversed_symbol_rate_lookup_results.rate)
  end

  def compute_minimum(rate_lookup_results),
    do: Decimal.mult(@minimum, rate_lookup_results.rate)
end

New error:

$ mix dialyzer
== Compilation error in file lib/Foo.ex ==
** (RuntimeError) Application.compile_env/3 cannot be called inside functions, only in the module body
    (elixir 1.12.2) lib/application.ex:507: Application."MACRO-compile_env"/4
    (elixir 1.12.2) expanding macro: Application.compile_env/2
    lib/Foo.ex:21: Foo.compute_minimum/1

What’s the best way to deal with the credo error?

I can’t reproduce the compile error you are seeing in your “Attempted Solution”? Application.compile_env/2 is the most appropriate call but the message suggests you are calling it inside a function somewhere?

2 Likes