Ecto 3 put_embed not accepting structs?

In upgrading from Ecto 2 to Ecto 3 I’m dealing with a failing test. If I use ExMachina build(:address) I’ll get an error trying to put_embed/3:

** (ArgumentError) unknown field `:__meta__` in %Orders.Schemas.InlineAddress{address: #Ecto.Association.NotLoaded<association :address is not loaded>, address_id: nil, city: nil, country_code: nil, delivery_instructions: nil, full_name: nil, id: nil, inserted_at: nil, line1: nil, line2: nil, override: nil, phone_number: nil, sap_id: nil, state_or_region: nil, type: nil, updated_at: nil, version: 1, zip_code: nil}
     code: exec(order: order, send_email: send_email_mock, send_csv: send_csv_mock, csv: true)
       (ecto 3.6.2) lib/ecto/changeset.ex:1225: Ecto.Changeset.put_change/7
       (stdlib 3.17) maps.erl:410: :maps.fold_1/3
       (ecto 3.6.2) lib/ecto/changeset.ex:396: Ecto.Changeset.change/2
       (ecto 3.6.2) lib/ecto/changeset/relation.ex:198: Ecto.Changeset.Relation.do_change/4
       (ecto 3.6.2) lib/ecto/changeset/relation.ex:326: Ecto.Changeset.Relation.single_change/5
       (ecto 3.6.2) lib/ecto/changeset/relation.ex:165: Ecto.Changeset.Relation.change/3
       (ecto 3.6.2) lib/ecto/changeset.ex:1213: Ecto.Changeset.put_change/7
       (ecto 3.6.2) lib/ecto/changeset.ex:1423: Ecto.Changeset.put_relation/5
       (packsize_data 0.0.1) ...accounting/schemas/vendor_po.ex:52: Accounting.VendorPO.changeset/2

vendor_po.ex referenced looks like:

  def changeset(%VendorPO{} = po, attrs) do
    |> cast(attrs, ~w[customer_po_number]a)
    |> put_embed_from_params(:shipping_address)

  defp put_embed_from_params(changeset, key) do
    put_embed(changeset, key, changeset.params["#{key}"])

Changing the test to params_for(:address) works. I don’t see anything in the Ecto docs that indicates something changed, to the contrary the documentation for put_assoc/3 states:

changesets or structs - when a changeset or struct is given, they are treated as the canonical data and the associated data currently stored in the association is ignored.

Nothing comes to mind but have you tried first updating only to Ecto 3.0 just to make sure the upgrade is as minimal as possible?

Yeah this is really strange, maybe it’s an error from exmachina, it does seem to be using ecto under the hood. Try to update the exmachina version, it might be a old version that doesn’t support ecto 3.

I just checked I’m on the latest of Exmachina, I’ll look into what @dimitarvp suggested at the moment Ecto looks locked at 3.6.2.