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
Every clause in a with chain must use <-, never =.
Why
<- is what gives with its reason for existing: a non-match aborts
the chain and returns the offending value as-is. A bare = line skips
that fall-through behavior - it's a local binding smuggled into the
chain to set up arguments for the next <- step. That bypasses the
one piece of control flow with is supposed to provide.
How to fix (two options)
Option 1 - bundle the infallible compute into the next fallible
helper so it emerges already wrapped in {:ok, _} | {:error, _} and
the with chain consumes it via <-:
# BAD
with :ok <- verify(),
argv = normalize_argv(raw_argv),
{:ok, opts} <- parse_options(argv) do
...
end
# GOOD
with :ok <- verify(),
{:ok, opts} <- parse_options(raw_argv) do
...
end
defp parse_options(raw_argv) do
raw_argv |> normalize_argv() |> OptionParser.parse(strict: @spec) |> ...
endOption 2 - move the binding into the do block. The do block is
normal Elixir code, so plain = bindings belong there. Use this when
the binding only feeds the body, not later with steps:
with :ok <- verify(),
{:ok, opts} <- parse_options(raw_argv) do
display = format_for_display(opts)
{:ok, display}
endWhat NOT to do
Do not "fix" this by wrapping the bare compute in {:ok, ...} inline
just to satisfy <-:
# STILL BAD - fake fallibility, no real control flow
with :ok <- verify(),
{:ok, argv} <- {:ok, normalize_argv(raw_argv)},
...If the step can't fail, it doesn't belong as a <- step. Pick one of
the two options above.
Check-Specific Parameters
There are no specific parameters for this check.
General Parameters
Like with all checks, general params can be applied.
Parameters can be configured via the .credo.exs config file.