Ash.Seed.upsert! failing with an UndefinedFunctionError in ash_postgres (that I am not directly calling)

Hi :wave:

I am trying to seed some data on my DB but I am getting an undefined error to a function that I am not directly calling.

This is the code of my priv/repo/seed.exs file:

alias Ash.Seed

_users =
  ["a@example", "b@example.com"]
  |> Enum.each(fn email ->
    Seed.upsert!(
      %Mcduck.Accounts.User{
        email: email
      },
      identity: :unique_email
    )
  end)

_rates =
  [
    ["EUR", "CHF", 0.93],
    ["CHF", "EUR", 1.083]
  ]
  |> Enum.each(fn [base_currency, target_currency, rate] ->
    Seed.seed!(%Mcduck.Money.Rates{
      base_currency: base_currency,
      target_currency: target_currency,
      rate: rate
    })
  end)

And this is the error when I run it with mix run priv/repo/seed.exs:

** (UndefinedFunctionError) function AshPostgres.DataLayer.upsert/3 is undefined or private. Did you mean:

      * upsert/4

    (ash_postgres 2.5.16) AshPostgres.DataLayer.upsert(Mcduck.Accounts.User, #Ash.Changeset<action_type: :create, action: nil, attributes: %{created_at: ~U[2025-04-17 08:56:02.046018Z], email: #Ash.CiString<"a@example.com">, id: "ec7864ae-43bc-450f-a52c-1df784c1ed42", updated_at: ~U[2025-04-17 08:56:02.046018Z]}, relationships: %{}, errors: [], data: #Mcduck.Accounts.User<__meta__: #Ecto.Schema.Metadata<:built, "users">, id: nil, email: nil, created_at: nil, updated_at: nil, aggregates: %{}, calculations: %{}, ...>, context: %{changed?: true}, valid?: true>, [:email])
    (ash 3.5.6) lib/ash/changeset/changeset.ex:4161: Ash.Changeset.run_around_actions/2
    (ash 3.5.6) lib/ash/changeset/changeset.ex:3839: anonymous fn/2 in Ash.Changeset.transaction_hooks/2
    (ash 3.5.6) lib/ash/changeset/changeset.ex:3749: Ash.Changeset.with_hooks/3
    (ash 3.5.6) lib/ash/seed.ex:289: Ash.Seed.upsert!/3
    (elixir 1.17.3) lib/enum.ex:987: Enum."-each/2-lists^foreach/1-0-"/2
    priv/repo/seeds.exs:17: (file)
    (elixir 1.17.3) lib/code.ex:1491: Code.require_file/2
    (mix 1.17.3) lib/mix/tasks/run.ex:146: Mix.Tasks.Run.run/5
    (mix 1.17.3) lib/mix/tasks/run.ex:85: Mix.Tasks.Run.run/1
    (mix 1.17.3) lib/mix/task.ex:495: anonymous fn/3 in Mix.Task.run_task/5
    (mix 1.17.3) lib/mix/cli.ex:96: Mix.CLI.run_task/2
    /etc/profiles/per-user/alex/bin/mix:2: (file)

I have updated to the latest versions of the dependencies including ash & ash_postgres.

A weird thing is that it worked at times just once when I updated just ash_postgres. Maybe it’s some cache somewhere trying to use a wrong function? I tried a mix clean and also:

❯ mix ash_postgres.drop && mix ash_postgres.create && mix ash_postgres.migrate && mix deps.update ash_postgres --force && mix run priv/repo/seeds.exs

Thanks!

Yes, it looks like we need to be using Code.ensure_loaded?(data_layer) before checking if functions are exported on it.

Fixed in main.

Great! Thanks for fixing it and doing it so quickly :pray:

1 Like

FTR in case that it helps anybody arriving here.

I am fixing it adding this prefix to the seeds file:

Code.ensure_loaded!(AshPostgres.DataLayer)