ForgeCredoChecks.NoApplicationGetEnvInLib (forge_credo_checks v0.8.0)

Copy Markdown View Source

Basics

This check is disabled by default.

Learn how to enable it via .credo.exs.

This check has a base priority of high and works with any version of Elixir.

Explanation

Application.get_env/2,3 is a runtime config read. Inside lib/ it is almost always the wrong reader: get_env silently returns nil (or a stale value) when the application environment is not yet loaded, so a compile-time configuration value is read as nil during releases and boot ordering races. Use Application.compile_env/2,3 for values that are fixed at compile time, or Application.fetch_env!/2 for values that are genuinely runtime-set and must fail loudly when missing.

Why

compile_env is evaluated when the module is compiled: the value is baked into the beam and is never re-read at runtime, so it cannot observe a half-loaded environment. get_env, by contrast, reads the live application environment every call. During a release boot the app env may not be loaded yet (or may carry a value from a previous boot phase), yielding nil or a stale value where a compile-time constant was intended. This class of bug is silent in mix and surfaces only in a packaged release.

Bad

# lib/my_app/config.ex
def timeout, do: Application.get_env(:my_app, :timeout)

Good

# lib/my_app/config.ex
def timeout, do: Application.compile_env(:my_app, :timeout)

Configuration

included_paths (default [~r"^lib/"]) lists path patterns (regexes or substrings) the check runs on; a file that matches none of them is skipped. allowed_paths (default []) lists path patterns that are permitted to use get_env even within scope — use it for the rare lib/ modules that legitimately read runtime config (a runtime-config registry, a hot-reload hook):

{ForgeCredoChecks.NoApplicationGetEnvInLib,
 allowed_paths: [~r"^lib/my_app/runtime/"]}

Application.fetch_env/2 and Application.fetch_env!/2 are deliberately out of scope for this check: they are the correct reader when a value is genuinely set at runtime and must fail loudly when absent. Only the silent get_env reader is flagged.

Check-Specific Parameters

Use the following parameters to configure this check:

:included_paths

Paths (regexes or substrings) the check runs on (default: lib/).

This parameter defaults to [~r/^lib\//].

:allowed_paths

In-scope paths permitted to use get_env (default: none).

This parameter defaults to [].

General Parameters

Like with all checks, general params can be applied.

Parameters can be configured via the .credo.exs config file.