Calculation with argument used in sort is failing because of actor not found

I have this calculation and action in my resource:

  calculations do
    calculate :normalized_address_similarity, :float do
      argument :address, :string, allow_nil?: true

      calculation expr(
                    fragment(
                      "CASE WHEN ?::text IS NOT NULL THEN word_similarity(?, ?) ELSE 0 END",
                      ^arg(:address),
                      ^arg(:address),
                      normalized_address
                    )
                  )
    end
  end

    read :list_own do
      alias Core.Ash.Preparations.WordSimilarityThreshold

      description "List appointments for the current user"
      transaction? true

      pagination offset?: true, countable: true, default_limit: 200, required?: true

      argument :start_date, :utc_datetime_usec, allow_nil?: true
      argument :end_date, :utc_datetime_usec, allow_nil?: true
      argument :address, :string, allow_nil?: true
      argument :similarity_threshold, :float, default: 0.80

      filter expr(
               assigned_to_id == ^actor(:id) and
                 (is_nil(^arg(:start_date)) or appointment_time >= ^arg(:start_date)) and
                 (is_nil(^arg(:end_date)) or appointment_time <= ^arg(:end_date)) and
                 (is_nil(^arg(:address)) or
                    fragment("(? %> ?)", normalized_address, ^arg(:address)))
             )

      prepare build(
                sort: [
                  normalized_address_similarity: {%{address: arg(:address)}, :desc}
                ]
              )
    end

When I run that action, I get the following error:

iex(86)> Core.Marketplace.Ap.Appointment.list_own(%{start_date: ~U[2024-08-16T14:06:17.200Z], end_date: ~U[2024-10-16T14:06:17.201Z]}, actor: actor)
[debug] QUERY OK db=0.1ms idle=1499.8ms
begin []
[debug] QUERY OK db=0.3ms
rollback []
** (KeyError) key :actor not found in: %{}
    (ash_sql 0.2.32) lib/expr.ex:1267: AshSql.Expr.default_dynamic_expr/6
    (ash_sql 0.2.32) lib/expr.ex:812: anonymous fn/6 in AshSql.Expr.default_dynamic_expr/6
    (elixir 1.17.2) lib/enum.ex:2531: Enum."-reduce/3-lists^foldl/2-0-"/3
    (ash_sql 0.2.32) lib/expr.ex:800: AshSql.Expr.default_dynamic_expr/6
    (ash_sql 0.2.32) lib/expr.ex:1408: AshSql.Expr.default_dynamic_expr/6
    (ash_sql 0.2.32) lib/sort.ex:225: anonymous fn/6 in AshSql.Sort.sort/6
    (elixir 1.17.2) lib/enum.ex:4858: Enumerable.List.reduce/3
    (elixir 1.17.2) lib/enum.ex:2585: Enum.reduce_while/3
    (ash_sql 0.2.32) lib/sort.ex:167: AshSql.Sort.sort/6
    (ash_sql 0.2.32) lib/query.ex:145: AshSql.Query.return_query/2
    (ash 3.4.8) lib/ash/query/query.ex:3025: Ash.Query.data_layer_query/2
    (ash 3.4.8) lib/ash/actions/read/read.ex:527: anonymous fn/8 in Ash.Actions.Read.do_read/5
    (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/read/read.ex:850: Ash.Actions.Read.maybe_in_transaction/3
    (ash 3.4.8) lib/ash/actions/read/read.ex:269: Ash.Actions.Read.do_run/3
    (ash 3.4.8) lib/ash/actions/read/read.ex:81: anonymous fn/3 in Ash.Actions.Read.run/3
    (ash 3.4.8) lib/ash/actions/read/read.ex:80: Ash.Actions.Read.run/3
    (ash 3.4.8) lib/ash.ex:1975: Ash.read/2
    iex:86: (file)

If I remove the sort, the action works. Not sure why it is searching for the actor since the calculation doesn’t use the actor at all.

Is normalized_address also a calculation?

It is an aggregation that fetches the value from another resource:

first :normalized_address, :lead, :normalized_address

Here is the field in the other resource:

attribute :normalized_address, :string, allow_nil?: false, public?: true

That resource doesn’t have any policies and uses the default :read action btw.

Fixed in main, will be in the next release. Tested and reproduced with a test in ash_postgres

1 Like

Thanks, fixed for me!