Ash Events - Datetime Won't Save

I’m attempting to create a resource that has a :datetime attribute:

attribute :pickup_time, :datetime do
  public? true
  allow_nil? false
end

The resource is setup with AshEvents and is set to log the events with the following code:

events do
    event_log(Api.Events.Event)
end

If I post to the creation endpoint with invalid data, like an integer for example, I get the expected error:

{
  "errors": [
    {
      "code": "invalid_attribute",
      "id": "6a24f1be-5c2c-497d-b860-246d8f7d0ecf",
      "meta": {},
      "status": "400",
      "title": "InvalidAttribute",
      "source": {
        "pointer": "/data/attributes/pickup_time"
      },
      "detail": "Could not cast input to datetime"
    }
  ],
  "jsonapi": {
    "version": "1.0"
  }
}

However if I send "pickup_time": "2025-07-15" or "pickup_time": "2025-07-15 00:00:00" then it seems to pass validation but (ash_events 0.4.2) lib/events/action_wrapper_helpers.ex:23 appears to throw a match error. (Value returned from dump_to_embedded is :error)

Full stack trace:

[error] ** (Ash.Error.Unknown) 
Bread Crumbs:
  > Exception raised in: Api.Shipments.Shipment.create

Unknown Error

* ** (MatchError) no match of right hand side value: :error
  (ash_events 0.4.2) lib/events/action_wrapper_helpers.ex:23: AshEvents.Events.ActionWrapperHelpers.dump_value/2
  (ash_events 0.4.2) lib/events/action_wrapper_helpers.ex:54: anonymous fn/2 in AshEvents.Events.ActionWrapperHelpers.create_event!/4
  (elixir 1.18.4) lib/enum.ex:1722: anonymous fn/3 in Enum.map/2
  (stdlib 6.2.2.1) maps.erl:860: :maps.fold_1/4
  (elixir 1.18.4) lib/enum.ex:2558: Enum.map/2
  (ash_events 0.4.2) lib/events/action_wrapper_helpers.ex:47: AshEvents.Events.ActionWrapperHelpers.create_event!/4
  (ash_events 0.4.2) lib/events/create_action_wrapper.ex:19: AshEvents.CreateActionWrapper.create/3
  (ash 3.5.26) lib/ash/actions/create/create.ex:309: anonymous fn/6 in Ash.Actions.Create.commit/3
  (ash 3.5.26) lib/ash/changeset/changeset.ex:4645: Ash.Changeset.run_around_actions/2
  (ash 3.5.26) lib/ash/changeset/changeset.ex:4181: anonymous fn/3 in Ash.Changeset.with_hooks/3
  (api 0.1.0) lib/api/repo.ex:2: anonymous fn/1 in Api.Repo."transaction (overridable 1)"/2
  (ecto 3.13.2) lib/ecto/repo/transaction.ex:7: anonymous fn/2 in Ecto.Repo.Transaction.transact/4
  (ecto_sql 3.13.2) lib/ecto/adapters/sql.ex:1458: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4
  (db_connection 2.8.0) lib/db_connection.ex:1753: DBConnection.run_transaction/4
  (ash 3.5.26) lib/ash/changeset/changeset.ex:4179: anonymous fn/3 in Ash.Changeset.with_hooks/3
  (ash 3.5.26) lib/ash/changeset/changeset.ex:4323: anonymous fn/2 in Ash.Changeset.transaction_hooks/2
  (ash 3.5.26) lib/ash/changeset/changeset.ex:4166: Ash.Changeset.with_hooks/3
  (ash 3.5.26) lib/ash/actions/create/create.ex:261: Ash.Actions.Create.commit/3
  (ash 3.5.26) lib/ash/actions/create/create.ex:132: Ash.Actions.Create.do_run/4
  (ash 3.5.26) lib/ash/actions/create/create.ex:50: Ash.Actions.Create.run/4
    (ash_events 0.4.2) lib/events/action_wrapper_helpers.ex:23: AshEvents.Events.ActionWrapperHelpers.dump_value/2
    (ash_events 0.4.2) lib/events/action_wrapper_helpers.ex:54: anonymous fn/2 in AshEvents.Events.ActionWrapperHelpers.create_event!/4
    (elixir 1.18.4) lib/enum.ex:1722: anonymous fn/3 in Enum.map/2
    (stdlib 6.2.2.1) maps.erl:860: :maps.fold_1/4
    (elixir 1.18.4) lib/enum.ex:2558: Enum.map/2
    (ash_events 0.4.2) lib/events/action_wrapper_helpers.ex:47: AshEvents.Events.ActionWrapperHelpers.create_event!/4
    (ash_events 0.4.2) lib/events/create_action_wrapper.ex:19: AshEvents.CreateActionWrapper.create/3
    (ash 3.5.26) lib/ash/actions/create/create.ex:309: anonymous fn/6 in Ash.Actions.Create.commit/3
    (ash 3.5.26) lib/ash/changeset/changeset.ex:4645: Ash.Changeset.run_around_actions/2
    (ash 3.5.26) lib/ash/changeset/changeset.ex:4181: anonymous fn/3 in Ash.Changeset.with_hooks/3
    (api 0.1.0) lib/api/repo.ex:2: anonymous fn/1 in Api.Repo."transaction (overridable 1)"/2
    (ecto 3.13.2) lib/ecto/repo/transaction.ex:7: anonymous fn/2 in Ecto.Repo.Transaction.transact/4
    (ecto_sql 3.13.2) lib/ecto/adapters/sql.ex:1458: anonymous fn/3 in Ecto.Adapters.SQL.checkout_or_transaction/4
    (db_connection 2.8.0) lib/db_connection.ex:1753: DBConnection.run_transaction/4
    (ash 3.5.26) lib/ash/changeset/changeset.ex:4179: anonymous fn/3 in Ash.Changeset.with_hooks/3
    (ash 3.5.26) lib/ash/changeset/changeset.ex:4323: anonymous fn/2 in Ash.Changeset.transaction_hooks/2
    (ash 3.5.26) lib/ash/changeset/changeset.ex:4166: Ash.Changeset.with_hooks/3
    (ash 3.5.26) lib/ash/actions/create/create.ex:261: Ash.Actions.Create.commit/3
    (ash 3.5.26) lib/ash/actions/create/create.ex:132: Ash.Actions.Create.do_run/4
    (ash 3.5.26) lib/ash/actions/create/create.ex:50: Ash.Actions.Create.run/4

I created a small reproduction repo: GitHub - thenhawke/ash_events_reporoduction

It’s related to Ash.Type.dump_to_embedded/3 call.
I was able to make this work:

iex(12)> d = DateTime.utc_now() |> DateTime.truncate(:second)
~U[2025-07-15 16:48:07Z]
iex(13)> Ash.Type.dump_to_embedded :utc_datetime_usec, d
{:ok, ~U[2025-07-15 16:48:07Z]}

:thinking: The docs say for dump_to_embedded:

  @doc """
  Casts a value from the Elixir type to a value that can be embedded in another data structure.

  Embedded resources expect to be stored in JSON, so this allows things like UUIDs to be stored
  as strings in embedded resources instead of binary.
  """

So not sure if this is even right. Should it be a string after the dump? :person_shrugging:

@thawke please open an issue on ash_events @Torkan is working on this area currently. In fact it may already be fixed in main, would be worth checking.

Hi @thawke!

Like @zachdaniel suggested, this issue should already be resolved in main.

Can you try using the main branch instead of the latest published version, and see if that works?

Can confirm this works in the main branch. Thanks!