Getting Ash.Error.Invalid.LimitRequired on Ash.Query.build

Following the documentation at Ash.Query — ash v2.21.5, if I write Ash.Query.build(LGS.Operacional.Estadia, limit: 1) |> LGS.Operacional.read, I get the following error

{:error,
 %Ash.Error.Invalid{
   errors: [
     %Ash.Error.Invalid.LimitRequired{
       changeset: nil,
       query: nil,
       error_context: [],
       vars: [],
       path: [],
       stacktrace: #Stacktrace<>,
       class: :invalid
     }
   ],
   stacktraces?: true,
   changeset: nil,
   query: #Ash.Query<
     resource: LGS.Operacional.Estadia,
     limit: 1,
     errors: [
       %Ash.Error.Invalid.LimitRequired{
         changeset: nil,
         query: nil,
         error_context: [],
         vars: [],
         path: [],
         stacktrace: #Stacktrace<>,
         class: :invalid
       }
     ]
   >,
   error_context: [nil],
   vars: [],
   path: [],
   stacktrace: #Stacktrace<>,
   class: :invalid
 }}

Ash version: “ash”: {:hex, :ash, “2.17.8”

What’s wrong with the query?

Thanks.

I believe this is coming from having required pagination on the resource. Pagination limits should be specified as LGS.Operacional.read(page: [limit: 1])

I think I didn’t get it Zach. What do you mean by “having required pagination on the resource”. Is it something that I put in the resource Estadia? I followed the documentation at Ash.Query — ash v2.17.8, where :limit is one of the options.
I’m trying to write an action using prepare(fn input, context -> ... end), but I’m not succeding on paginating using keyset. Any guidance is welcome. Thanks.

Can I see the read action you’re calling? I’m suspecting that you have something like:

pagination keyset?: true

By default, when you add that, it makes pagination required. To paginate, you don’t provide the limit with Ash.Query.limit, you provide it as an option when reading, i.e LGS.Operacional.read(page: [limit: 1])

read :list do
  prepare(fn input, context ->
    Estadia
    |> Ash.Query.filter(localizador_externo: "123456")
  end)
  pagination(keyset?: true, default_limit: 1, countable: true)
end

I’m also trying to receive a list of tuples argument, like: [{"a", 1}, {"b", 2}, ...], but I couldn’t get the argument function to work.

There isn’t a builtin type for tuples, so you’d need to write a custom one and/or use the :term type to accept a value of any type.

Interesting, it seems like default_limit is not being applied.

1 Like

I’ve just pushed something to main that might help. Please try it out and let me know.

I’ll try in a minute. Before that, could you help me with another question?
The following code

read :list do
      prepare(fn input, context ->
        query = Estadia
        |> Ash.Query.build(load: [
          :entrada_parceiro,
          :entrada_via,
          :faturamentos,
          :saida_via,
          entrada_plano_contrato: :pessoa
        ], limit: 1)

        filters = [
          {"localizadores", "123456"}
        ]

        Enum.reduce(filters, query, fn
          {"localizadores", value}, query ->
            Ash.Query.filter(query, value in localizadores)
          filter, query ->
            Ash.Query.filter(query, filter)
        end)
      end)
      # pagination(keyset?: true, default_limit: 1, countable: true)
    end

gives me the following error

{:error,
 %Ash.Error.Unknown{
   errors: [
     %Ash.Error.Unknown.UnknownError{
       error: "filter: Invalid reference value",
       field: nil,
       changeset: nil,
       query: nil,
       error_context: [],
       vars: [],
       path: [:filter],
       stacktrace: #Stacktrace<>,
       class: :unknown
     }
   ],
   stacktraces?: true,
   changeset: nil,
   query: #Ash.Query<
     resource: LGS.Operacional.Estadia,
     limit: 1,
     load: [
       entrada_parceiro: [],
       entrada_via: [],
       faturamentos: [],
       saida_via: [],
       entrada_plano_contrato: #Ash.Query<
         resource: LGS.Operacional.PlanoContrato,
         load: [pessoa: []]
       >
     ],
     errors: [
       %Ash.Error.Unknown.UnknownError{
         error: "filter: Invalid reference value",
         field: nil,
         changeset: nil,
         query: nil,
         error_context: [],
         vars: [],
         path: [:filter],
         stacktrace: #Stacktrace<>,
         class: :unknown
       }
     ]
   >,
   error_context: [nil],
   vars: [],
   path: [],
   stacktrace: #Stacktrace<>,
   class: :unknown
 }}

Even with the main branch, the action returns %Ash.Page.Offset{}.

You need to pin variable references, like so: Ash.Query.filter(query, ^value in localizadores)

1 Like

Great. Worked. Thanks.

1 Like