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
Builtin change, validation, preparation, and calculation functions
like set_attribute, present, build, and concat must be
wrapped in their DSL entity (change, validate, prepare,
calculate ...) when used inside an action body, a pipeline body,
or a global section (changes, validations, preparations,
calculations).
These builtins are plain functions imported into the DSL scope. Without the wrapper, the call returns a spec tuple that is silently discarded - the change/validation/preparation never runs and no error or warning is raised at compile time or runtime.
# Bad - compiles but silently does nothing
create :register do
accept [:email]
present(:email)
set_attribute(:status, :draft)
end
# Good - wrapped in the matching keyword
create :register do
accept [:email]
validate present(:email)
change set_attribute(:status, :draft)
endEach builtin family is only checked in the scopes that import it, so
a bare call the compiler already rejects is never flagged. The advice
is position-aware for set_context, which exists as both a change
and a preparation builtin: in pipelines it gets change, in read and
generic actions prepare.
The builtin names are read from Ash's *.Builtins modules at analysis
time, so builtins added in newer Ash versions are covered automatically.
Because some of them are common words (present, compare, match,
build, load, select), a bare call to a same-named local helper
inside an action body would be flagged too; silence such a call with
# credo:disable-for-next-line.
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.