Tenant not being recognised in load after upgrading to Ash 2.9.21

Hi, I'm trying to upgrade to the latest version of Ash (2.9.21) and my tests are failing after the upgrade. In particular, I have code like this:
MyApi.load!(record, :some_calculation, tenant: t)
MyApi.load!(record, :some_calculation, tenant: t)
which previously worked, but now is giving an error of the form:
%Ash.Error.Invalid{
errors: [%Ash.Error.Invalid.TenantRequired{
resource: MyApi.MyParentResource, changeset: nil, query: nil, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}], stacktraces?: true, changeset: nil, query: #Ash.Query<resource: MyApi.MyChildResource, tenant: "org_tenant-id", calculations: %{some_calculation: #MyApi.Resources.MyChildResource.Calculations.SomeCalculation<[]>}, errors: [%Ash.Error.Invalid{errors: [%Ash.Error.Invalid.TenantRequired{resource: MyApi.MyParentResource, changeset: nil, query: nil, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}], stacktraces?: true, changeset: nil, query: #Ash.Query<resource: MyApi.MyParentResource, filter: #Ash.Filter<id == "02a8b6ac-140c-456e-b4a2-c4d5287bbbe3">, errors: [%Ash.Error.Invalid.TenantRequired{resource: MyApi.MyParentResource, changeset: nil, query: nil, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}], select: [:id, :inserted_at, :updated_at, ... :MyParentResource_type, ...]>, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}, %Ash.Error.Invalid.TenantRequired{resource: MyApi.MyParentResource, changeset: nil, query: nil, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}]>, error_context: [nil], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}
%Ash.Error.Invalid{
errors: [%Ash.Error.Invalid.TenantRequired{
resource: MyApi.MyParentResource, changeset: nil, query: nil, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}], stacktraces?: true, changeset: nil, query: #Ash.Query<resource: MyApi.MyChildResource, tenant: "org_tenant-id", calculations: %{some_calculation: #MyApi.Resources.MyChildResource.Calculations.SomeCalculation<[]>}, errors: [%Ash.Error.Invalid{errors: [%Ash.Error.Invalid.TenantRequired{resource: MyApi.MyParentResource, changeset: nil, query: nil, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}], stacktraces?: true, changeset: nil, query: #Ash.Query<resource: MyApi.MyParentResource, filter: #Ash.Filter<id == "02a8b6ac-140c-456e-b4a2-c4d5287bbbe3">, errors: [%Ash.Error.Invalid.TenantRequired{resource: MyApi.MyParentResource, changeset: nil, query: nil, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}], select: [:id, :inserted_at, :updated_at, ... :MyParentResource_type, ...]>, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}, %Ash.Error.Invalid.TenantRequired{resource: MyApi.MyParentResource, changeset: nil, query: nil, error_context: [], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}]>, error_context: [nil], vars: [], path: [], stacktrace: #Stacktrace<>, class: :invalid}
Basically I'm trying to load a calculation on a resource that has a related parent - and now it's not picking the tenant up. The API of the load function seems the same after the version bump - Any ideas what has changed here?
22 Replies
kernel
kernel•2y ago
random but can you try setting the tenant with Ash.set_tenant/1 beforehand?
Adam Harris
Adam HarrisOP•2y ago
@kernel thanks for the suggestion! If I call Ash.set_tenant(t) at the start of the test I get the following:
** (RuntimeError) Engine Deadlock! No async tasks and state is the same after iteration.
** (RuntimeError) Engine Deadlock! No async tasks and state is the same after iteration.
kernel
kernel•2y ago
🙀 crazy, I didn't actually think you would need to add tenant as an opt for the load to begin with (as your record should have the tenant set in the metadata field)
Adam Harris
Adam HarrisOP•2y ago
@Zach Daniel could this be a bug?
ZachDaniel
ZachDaniel•2y ago
an engine deadlock is 100% a bug What version did you upgrade from?
Adam Harris
Adam HarrisOP•2y ago
2.6.21
ZachDaniel
ZachDaniel•2y ago
oh damn 😆
Adam Harris
Adam HarrisOP•2y ago
it looks like the tenant id is not being passed from a child to parent in a query for a calculation...? could this be causing a bug, that then manifests in the deadlock?
ZachDaniel
ZachDaniel•2y ago
Okay, so when you say it has a related parent, do you mean the calculation depends on the parent record? yeah, that is the likely cause I'm thinking it should be a relatively simple change to get the tenant where it needs to be here
Adam Harris
Adam HarrisOP•2y ago
yes - the calculation in the child depends on the parent. it has the following code at the top of the calculation:
...
@impl true
def load(_query, _opts, _context), do: [:parent]

@impl true
def calculate(records, _opts, _) do
Enum.map(records, fn child ->
p = child.parent
...
...
@impl true
def load(_query, _opts, _context), do: [:parent]

@impl true
def calculate(records, _opts, _) do
Enum.map(records, fn child ->
p = child.parent
...
ZachDaniel
ZachDaniel•2y ago
can you try main? actually...I'm still not 100% sure. That might fix it, lemme konw
Adam Harris
Adam HarrisOP•2y ago
@Zach Daniel it didn't fix it - still getting the TenantRequired error
ZachDaniel
ZachDaniel•2y ago
Okay, thought that might happen is there a stacktrace?
Adam Harris
Adam HarrisOP•2y ago
** (Ash.Error.Invalid) Input Invalid

* Queries against the MyApi.MyParentResource resource require a tenant to be specified
(ash 2.9.21) lib/ash/actions/read.ex:612: Ash.Actions.Read.validate_multitenancy/1
(ash 2.9.21) lib/ash/actions/read.ex:325: anonymous fn/12 in Ash.Actions.Read.as_requests/5
(ash 2.9.21) lib/ash/engine/request.ex:1063: Ash.Engine.Request.do_try_resolve_local/4
(ash 2.9.21) lib/ash/engine/request.ex:932: Ash.Engine.Request.do_try_resolve/5
(elixir 1.14.5) lib/enum.ex:4751: Enumerable.List.reduce/3
(elixir 1.14.5) lib/enum.ex:2514: Enum.reduce_while/3
(ash 2.9.21) lib/ash/engine/request.ex:998: Ash.Engine.Request.do_try_resolve_local/4
(ash 2.9.21) lib/ash/engine/request.ex:282: Ash.Engine.Request.do_next/1
(ash 2.9.21) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1
(ash 2.9.21) lib/ash/engine/engine.ex:712: Ash.Engine.advance_request/2
(ash 2.9.21) lib/ash/engine/engine.ex:637: Ash.Engine.fully_advance_request/2
(ash 2.9.21) lib/ash/engine/engine.ex:578: Ash.Engine.do_run_iteration/2
(elixir 1.14.5) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.21) lib/ash/engine/engine.ex:307: Ash.Engine.run_to_completion/1
(ash 2.9.21) lib/ash/engine/engine.ex:252: Ash.Engine.do_run/2
(ash 2.9.21) lib/ash/engine/engine.ex:148: Ash.Engine.run/2
(ash 2.9.21) lib/ash/actions/read.ex:173: Ash.Actions.Read.do_run/3
(ash 2.9.21) lib/ash/actions/read.ex:96: Ash.Actions.Read.run/3
** (Ash.Error.Invalid) Input Invalid

* Queries against the MyApi.MyParentResource resource require a tenant to be specified
(ash 2.9.21) lib/ash/actions/read.ex:612: Ash.Actions.Read.validate_multitenancy/1
(ash 2.9.21) lib/ash/actions/read.ex:325: anonymous fn/12 in Ash.Actions.Read.as_requests/5
(ash 2.9.21) lib/ash/engine/request.ex:1063: Ash.Engine.Request.do_try_resolve_local/4
(ash 2.9.21) lib/ash/engine/request.ex:932: Ash.Engine.Request.do_try_resolve/5
(elixir 1.14.5) lib/enum.ex:4751: Enumerable.List.reduce/3
(elixir 1.14.5) lib/enum.ex:2514: Enum.reduce_while/3
(ash 2.9.21) lib/ash/engine/request.ex:998: Ash.Engine.Request.do_try_resolve_local/4
(ash 2.9.21) lib/ash/engine/request.ex:282: Ash.Engine.Request.do_next/1
(ash 2.9.21) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1
(ash 2.9.21) lib/ash/engine/engine.ex:712: Ash.Engine.advance_request/2
(ash 2.9.21) lib/ash/engine/engine.ex:637: Ash.Engine.fully_advance_request/2
(ash 2.9.21) lib/ash/engine/engine.ex:578: Ash.Engine.do_run_iteration/2
(elixir 1.14.5) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.21) lib/ash/engine/engine.ex:307: Ash.Engine.run_to_completion/1
(ash 2.9.21) lib/ash/engine/engine.ex:252: Ash.Engine.do_run/2
(ash 2.9.21) lib/ash/engine/engine.ex:148: Ash.Engine.run/2
(ash 2.9.21) lib/ash/actions/read.ex:173: Ash.Actions.Read.do_run/3
(ash 2.9.21) lib/ash/actions/read.ex:96: Ash.Actions.Read.run/3
stacktrace:
(ash 2.9.21) lib/ash/error/error.ex:461: Ash.Error.choose_error/2
(ash 2.9.21) lib/ash/error/error.ex:218: Ash.Error.to_error_class/2
(ash 2.9.21) lib/ash/actions/read.ex:184: Ash.Actions.Read.do_run/3
(ash 2.9.21) lib/ash/actions/read.ex:96: Ash.Actions.Read.run/3
(ash 2.9.21) lib/ash/actions/load.ex:783: anonymous fn/11 in Ash.Actions.Load.calc_dep_data/12
(ash 2.9.21) lib/ash/engine/request.ex:1048: Ash.Engine.Request.do_try_resolve_local/4
(ash 2.9.21) lib/ash/engine/request.ex:282: Ash.Engine.Request.do_next/1
(ash 2.9.21) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1
(ash 2.9.21) lib/ash/engine/engine.ex:712: Ash.Engine.advance_request/2
(ash 2.9.21) lib/ash/engine/engine.ex:637: Ash.Engine.fully_advance_request/2
(ash 2.9.21) lib/ash/engine/engine.ex:578: Ash.Engine.do_run_iteration/2
(elixir 1.14.5) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.21) lib/ash/engine/engine.ex:307: Ash.Engine.run_to_completion/1
(ash 2.9.21) lib/ash/engine/engine.ex:252: Ash.Engine.do_run/2
(ash 2.9.21) lib/ash/engine/engine.ex:148: Ash.Engine.run/2
(ash 2.9.21) lib/ash/actions/read.ex:173: Ash.Actions.Read.do_run/3
(ash 2.9.21) lib/ash/actions/read.ex:96: Ash.Actions.Read.run/3
(ash 2.9.21) lib/ash/api/api.ex:1657: Ash.Api.load/4
stacktrace:
(ash 2.9.21) lib/ash/error/error.ex:461: Ash.Error.choose_error/2
(ash 2.9.21) lib/ash/error/error.ex:218: Ash.Error.to_error_class/2
(ash 2.9.21) lib/ash/actions/read.ex:184: Ash.Actions.Read.do_run/3
(ash 2.9.21) lib/ash/actions/read.ex:96: Ash.Actions.Read.run/3
(ash 2.9.21) lib/ash/actions/load.ex:783: anonymous fn/11 in Ash.Actions.Load.calc_dep_data/12
(ash 2.9.21) lib/ash/engine/request.ex:1048: Ash.Engine.Request.do_try_resolve_local/4
(ash 2.9.21) lib/ash/engine/request.ex:282: Ash.Engine.Request.do_next/1
(ash 2.9.21) lib/ash/engine/request.ex:211: Ash.Engine.Request.next/1
(ash 2.9.21) lib/ash/engine/engine.ex:712: Ash.Engine.advance_request/2
(ash 2.9.21) lib/ash/engine/engine.ex:637: Ash.Engine.fully_advance_request/2
(ash 2.9.21) lib/ash/engine/engine.ex:578: Ash.Engine.do_run_iteration/2
(elixir 1.14.5) lib/enum.ex:2468: Enum."-reduce/3-lists^foldl/2-0-"/3
(ash 2.9.21) lib/ash/engine/engine.ex:307: Ash.Engine.run_to_completion/1
(ash 2.9.21) lib/ash/engine/engine.ex:252: Ash.Engine.do_run/2
(ash 2.9.21) lib/ash/engine/engine.ex:148: Ash.Engine.run/2
(ash 2.9.21) lib/ash/actions/read.ex:173: Ash.Actions.Read.do_run/3
(ash 2.9.21) lib/ash/actions/read.ex:96: Ash.Actions.Read.run/3
(ash 2.9.21) lib/ash/api/api.ex:1657: Ash.Api.load/4
ZachDaniel
ZachDaniel•2y ago
okay, pushed something up again that might do it if this doesn't work then we're going to need to get a test reproduction in ash
Adam Harris
Adam HarrisOP•2y ago
no, I'm getting the same error unfortunately
ZachDaniel
ZachDaniel•2y ago
damn. Okay, so the best way for me to fix this would be a test file that defines two multitenant resources and has a similar calculation.
Adam Harris
Adam HarrisOP•2y ago
I’ll try and sort one for you tomorrow morning and stick it in a pull request if that would help?
ZachDaniel
ZachDaniel•2y ago
That would help immensely 🙂 Got a lot of plates spinning at the moment, that will make things much easier
Adam Harris
Adam HarrisOP•2y ago
GitHub
added failing test showing that calculations cannot access attribut...
… of parent in multitenant context due to bug causing tenant id not being present Contributor checklist added failing test for minimal reproduction of bug relates to issue #605
Adam Harris
Adam HarrisOP•2y ago
Sorry it's a bit messy and brief - I had very little time this morning so put it together in a rush I edited one of the test files relating to calculations, adding a failing test fro accessing a calculation on a parent from a child, in a multitenant context
ZachDaniel
ZachDaniel•2y ago
Beautiful, thanks!

Did you find this page helpful?