Skip to content

Fix/1877 notification shapes - #2991

Merged
zachdaniel merged 9 commits into
ash-project:mainfrom
MichaelL0827:fix/1877-notification-shapes
Oct 7, 2026
Merged

zachdaniel merged 9 commits into
ash-project:mainfrom
MichaelL0827:fix/1877-notification-shapes

Conversation

@MichaelL0827

Copy link
Copy Markdown
Contributor

Summary

Closes #1877

Normalizes notification values returned from before-action and after-action hooks.

Hooks can now return notifications as:

  • A single notification
  • A list of notifications
  • A map containing a :notifications key
  • nil

This behavior is shared across Ash.ActionInput and Ash.Changeset hooks.

Note: the linked issue only mentioned Ash.Changeset, but Ash.ActionInput had the identical inconsistency (same two shapes, same crash pattern), so it's fixed here as well for consistency.

Root Cause

Ash.Notifier.Notification had no shared type or normalization function for its hook-return shapes. As a result, action_input.ex and changeset.ex each accepted a different shape at different call sites: before_action hooks expected %{notifications: [...]}} while after_action hooks expected a bare list. Returning the "wrong" shape for a given hook crashed with a BadMapError or KeyError rather than working consistently.

Changes

  • Notification.ex: added Ash.Notifier.Notification.input/0 (the union type) and normalize/1, which converts any accepted shape into a flat list.
  • Changeset.ex: run_before_actions and run_after_actions now call normalize/1 instead of pattern-matching/List.wrap-ing a single hardcoded shape.
  • action_input.ex: identical changes to run_before_actions and merge_after_action_notifications.
  • Updated docs in action_input.ex, changeset.ex, and actions.md to reflect the accepted notification shapes.
  • Added regression tests for notification return shapes in notifier_test.exs and generic_actions_test.exs.

Testing

  • added tests: "a custom notification can be returned as a bare list from an after_action hook", "a custom notification can be returned as a map from an after_action hook", "notifications from before and after action hooks are both delivered", "all notifications returned from an after_action hook are delivered", "a custom notification can be returned as a bare list from a before_action hook", "before_action hooks can return notifications as a bare list", "after_action hooks can return notifications as a map"
  • Tests fail without this change: yes
  • mix check and mix dialyzer pass locally: yes

Contributor checklist

Leave anything that you believe does not apply unchecked.

  • I accept the AI Policy, or AI was not used in the creation of this PR.
  • Bug fixes include regression tests
  • Chores
  • Documentation changes
  • Features include unit/acceptance tests
  • Refactoring
  • Update dependencies

Copilot AI balanced review requested due to automatic review settings October 7, 2026 02:53

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@zachdaniel
zachdaniel merged commit f81afa6 into ash-project:main Oct 7, 2026
51 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Standardize type for returning extra notifications from hook functions and manual actions

3 participants