and here comes the next one (I did observe the behaviour and checked that the referenced code exists)
Ash Framework Issue: Runtime Upsert Options Not Properly Passed to Data Layers
Problem Summary
When using Ash.create/3 with runtime upsert options (like upsert?: false, upsert_fields: [...]), these options are not properly handled or passed to the data layer, causing incorrect behavior.
Issues Identified
Issue 1: Runtime upsert?: false is ignored when action has upsert?: true
Location: lib/ash/actions/create/create.ex, lines 100-104
Current code:
opts =
opts
|> Keyword.put(
:upsert?,
action.upsert? || opts[:upsert?] || get_in(changeset.context, [:private, :upsert?]) || false
)
Problem: The OR logic means if action.upsert? is true, runtime opts[:upsert?] = false is ignored.
Expected behavior: Runtime options should override action settings.
Issue 2: Runtime upsert_fields option is never passed to data layer
Location: lib/ash/actions/create/create.ex, lines 125-127
Current code:
changeset =
Ash.Changeset.set_context(changeset, %{
private: %{upsert?: true, upsert_identity: upsert_identity}
# Missing: upsert_fields from opts
})
Problem: Unlike bulk_create which properly sets upsert_fields in the changeset context, regular create doesn’t.
Compare with bulk_create (lib/ash/actions/create/bulk.ex):
|> Map.put(:context, %{
private: %{
upsert?: opts[:upsert?] || action.upsert? || false,
upsert_identity: opts[:upsert_identity] || action.upsert_identity,
upsert_fields: Ash.Changeset.expand_upsert_fields(
opts[:upsert_fields] || action.upsert_fields, # <-- Properly handled
resource
)
}
})
Expected behavior: Runtime upsert_fields should be accessible to data layers via changeset.context[:private][:upsert_fields].
to be clear: my expectation is that we should be able to set upsert_fields as a runtime option, but maybe this is not possible for a normal create action … but in that case it would be nice if ash complained when I tried to do this