# `AshGrant.Changes.ResolveArgument`
[🔗](https://github.com/jhlee111/ash_grant/blob/v0.14.1/lib/ash_grant/changes/resolve_argument.ex#L1)

Runtime change that lazily populates an action argument from the record's
own relationships.

Installed automatically by `AshGrant.Transformers.AddArgumentResolvers` when a
resource declares `resolve_argument` in its `ash_grant` block. Users rarely
reference this module directly.

## Options

  * `:name` — argument name to set
  * `:path` — list of atoms walking relationships to a leaf attribute
    (e.g. `[:order, :center_id]`, `[:order, :customer, :organization_id]`).
    Intermediate keys are belongs_to relationships; the last is an attribute.
  * `:scopes_needing` — list of scope atoms whose resolved filter references
    `^arg(<name>)`. Injected by the transformer at compile time.

## Runtime contract

If the actor is nil, or none of the actor's permissions (as returned by the
resource's configured `AshGrant.PermissionResolver`) use a scope in
`:scopes_needing`, the change is a no-op — no DB load is performed.

If the resource has no resolver configured, or the resolver raises/returns
an unexpected shape, the change conservatively resolves the argument
rather than skipping — otherwise production actors (Ash resource structs
that carry no literal `:permissions` field) would silently bypass the
resolver.

Otherwise, the change resolves the path:

  * **create**: read the first-hop foreign key from the changeset's
    attributes, fetch the head record, then walk the remaining path keys
    through loaded relationships.
  * **update/destroy**: load the relationship path on `changeset.data`, then
    read the leaf attribute.

If any intermediate value is nil or the path cannot be resolved (e.g., the
referenced record was deleted), the change returns the changeset unchanged —
the scope will then evaluate against a `nil` argument and typically fail
closed (authorization denied).

## Multi-tenancy

The changeset's `:tenant` is forwarded to the internal `Ash.get!`/`Ash.load!`
calls so that resources along `from_path` using attribute multitenancy can be
fetched correctly. Without this, those fetches would raise, be rescued, and
leave the argument unset — causing the scope to evaluate to `false`.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
