Change not being called when running bulk_create

I think I already asked that some time ago but I couldn’t find the topic, so I’m sorry if this is a duplicated question…

I have a create action that has a change on it:

    create :create_with_phone_number do
      accept @all_fields -- [:email, :normalized_full_name, :normalized_full_name_version]

      upsert? true
      upsert_identity :unique_phone_number
      upsert_fields []

      change Changes.NormalizeFullName
    end

Here is the change:

defmodule Core.Pacman.Markets.SkipTrace.Changes.NormalizeFullName do
  @moduledoc false

  use Ash.Resource.Change

  def change(changeset, _opts, _context) do
    Ash.Changeset.before_action(changeset, &do_change/1)
  end

  defp do_change(changeset) do
    ...
  end
end

That change will calculate the field :normalized_full_name.

I’m using that function in bulk_create call like this:

            %{status: :success, records: phone_numbers_skip_traces} =
              Ash.bulk_create(phone_numbers, SkipTrace, :create_with_phone_number,
                return_records?: true,
                return_errors?: true,
                timeout: :infinity
              )

What I found is that the change is not being called, it does call the def change function where I call Ash.Changeset.before_action/2, but the do_change/2 is never called and then I get this error:

[error] Task #PID<0.5458.0> started from #PID<0.5451.0> terminating
** (MatchError) no match of right hand side value: %Ash.BulkResult{status: :error, errors: [%Ash.Error.Invalid{changeset: "#Changeset<>",  errors: [%Ash.Error.Changes.Required{field: :normalized_full_name, type: :attribute, resource: Core.Pacman.Markets.SkipTrace, splode: Ash.Error, bread_crumbs: [], vars: [], path: [], stacktrace: #Splode.Stacktrace<>, class: :invalid}]}, %Ash.Error.Invalid{changeset: "#Changeset<>",  errors: [%Ash.Error.Changes.Required{field: :normalized_full_name, type: :attribute, resource: Core.Pacman.Markets.SkipTrace, splode: Ash.Error, bread_crumbs: [], vars: [], path: [], stacktrace: #Splode.Stacktrace<>, class: :invalid}]}], records: [], notifications: [], error_count: 2}
    (core 1.88.1) lib/core/pacman/markets/skip_trace/actions/search.ex:24: anonymous fn/4 in Core.Pacman.Markets.SkipTrace.Actions.Search.run/2
    (ecto_sql 3.12.0) lib/ecto/adapters/sql.ex:1382: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4
    (db_connection 2.7.0) lib/db_connection.ex:1756: DBConnection.run_transaction/4
    (ash 3.4.8) lib/ash/actions/action.ex:129: Ash.Actions.Action.run/3
    (ash 3.4.8) lib/ash.ex:1376: Ash.run_action/2
    (ash 3.4.8) lib/ash.ex:1347: Ash.run_action!/2
    (core 1.88.1) lib/core_web/components/admin/skip_trace/search.ex:117: CoreWeb.Components.Admin.SkipTrace.Search.do_search/3
    (phoenix_live_view 0.20.17) lib/phoenix_live_view/async.ex:220: Phoenix.LiveView.Async.do_async/5
    (elixir 1.17.2) lib/task/supervised.ex:101: Task.Supervised.invoke_mfa/2
Function: #Function<7.72073719/0 in Phoenix.LiveView.Async.run_async_task/5>
    Args: []

Again, that change is responsible to calculate the field normalized_full_name field, so if the change was called, that field would be set and that error would not occur.

An I doing something wrong here? That action worked in Ash 2 (I’m upgrading it to 3.0 right now).

I don’t see anything wrong with it currently :thinking: I’m a broken record, but you’re definitely on the latest version of ash?

Yep, Ash 3.4.8

please open an issue on the ash repo in that case, i will investigate tomorrow.

It would be useful to share the logic of how the normalized_full_name is being set.

Is it being set if you create a single record, not with a bulk insert?

The logic is just a Ash.Changeset.force_change_attribute, I didn’t add that to the original post because the do_change/1 which has that logic is never called.

I just tried with a single insert and it works just fine.

@zachdaniel, I will try to create a small reproducible example and create the issue.

Here is the issue: Change not being called with bulk_create · Issue #1449 · ash-project/ash · GitHub

Fixed after this commit fix: require private/non-accepted attributes after before action hooks · ash-project/ash@2e2ab0e · GitHub

Thanks @zachdaniel

1 Like