Ecto traverse_errors - getting to the values triggering the errors?


I’m using traverse_errors as described here: to gather validation errors from a schema with an embed_many.

I get the following output (truncated for readability):

  mods: [
    %{value: ["is invalid"]},
    %{value: ["is invalid"]},
    %{value: ["is invalid"]},
    %{value: [...]},

I would like to include the actual values that trigger the invalid failures, but can’t see any obvious way of doing it. Neither the Changeset.changes nor Changeset.errors seem to contain this information?

Any tips would be appreciated, thanks

changeset.params contains values that are being casted, I think you’d have to manually traverse changesets (like traverse_errors does it) to match up values with errors.

Sounds like you might get what you’re looking for with the behavior traverse_errors has when you pass a function with arity 3, referenced briefly in the documentation:

Optionally function can accept three arguments: changeset, field and error tuple {msg, opts}.
It is useful whenever you want to extract validations rules from changeset.validations to build detailed error description.

Combining the first two args using Ecto.Changeset.get_change(changeset, field) will get you the value that triggered the validation error.

1 Like


Thanks for the replies.

I have been testing with passing a function with arity 3 now and that gives me access to the entire changeset. get_change was convenient, but it seems if the error is a cast error then Changeset.changes doesn’t include the key:value pair that failed at all. If the error was an inclusion error it is included.