# What changed in next-safe-action

> 50 changes in next-safe-action 8 from its official release notes, upgrade guides and advisories: 12 breaking, 5 deprecations, 2 security, 8 new APIs and options. Each one cited. Sources checked 2026-10-22. HTML: https://unstale.sh/npm/next-safe-action/

To see which of these apply to a repository, run `npx @unstale/cli init` in it.

## next-safe-action 8

### Breaking changes

- Queued dispatches marked stale by reset() no longer call the action or write to the server; their executeAsync promises resolve with {} and their callbacks do not fire. Applies to useStateAction and useOptimisticStateAction. (8.7.1) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.1)
- Adds an optimistic hook for stateful actions. Dispatches queue, each receives the previous result, and optimistic updates can accumulate instead of using last-write-wins behavior. (8.7.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.0)
- Output schema transforms and defaults are applied to returned data and the onSuccess callback, rather than using the raw action return value. (8.6.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.0)
- In useAction and useOptimisticAction, reset() invalidates in-flight executions so pending responses cannot repopulate hook state. (8.6.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.0)
- All hooks report idle status immediately after reset, even while an uncancellable in-flight execution is still settling. (8.6.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.0)
- Passing a non-JSON-serializable payload now throws a clear error instead of leaking a raw TypeError. (8.5.5) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.5)
- The library no longer has deepmerge-ts as a runtime dependency; it now ships with zero runtime dependencies. (8.5.3) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.3)
- Action results now prioritize validationErrors, then serverError, then data, so only one of these fields is populated when multiple errors occur. (8.5.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.0)
- The transitioning value was removed from the HookActionStatus union; the isTransitioning boolean on the hook return object is unchanged. (8.5.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.0)
- Hook return types are now discriminated unions keyed on status; utilities such as Pick, Omit, and Partial distribute over the union, and constructed values must match one branch. (8.5.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.0)
- Callbacks now fire immediately after an action completes. (8.1.2) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/v8.1.2)
- Navigation errors are thrown immediately to support Next.js Cache Components. (8.1.1) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/v8.1.1)

### Security

- Validation issue paths are traversed safely, and hostile keys are stored as own properties so they cannot modify the global prototype. (8.5.5) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.5)
- Field keys are assigned safely to prevent hostile keys from modifying the global prototype. (8.5.5) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.5)

### Deprecations

- Renames the exported type SafeActionUtils; SafeActionUtils remains available as a deprecated alias. (8.1.9) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.9)
- Renames the exported type HookSafeActionFn; HookSafeActionFn remains available as a deprecated alias. (8.1.9) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.9)
- Renames the exported type HookSafeStateActionFn; HookSafeStateActionFn remains available as a deprecated alias. (8.1.9) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.9)
- Renames the exported type StateServerCodeFn; StateServerCodeFn remains available as a deprecated alias. (8.1.9) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.9)
- Renames the exported type DVES; DVES remains available as a deprecated alias. (8.1.9) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.9)

### New APIs and options

- Adds an option to useAction and useOptimisticAction that seeds the hook with an initial result; reset() restores it. (8.6.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.0)
- Adds a utility for returning typed, expected server errors to the client as result.serverError, bypassing handleServerError. (8.6.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.0)
- Adds post-validation middleware with type-safe context. (8.4.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.4.0)
- Adds a flag to internal hooks, defaulting to false; when true, navigation functions such as forbidden() and notFound() navigate to an error page, and onNavigation and onSettled callbacks cannot be used. (8.2.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.2.0)
- Exported from the core package so developers can use it. (8.1.10) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.10)
- Exported from the core package so developers can use it. (8.1.10) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.10)
- Exported from the core package so developers can use it. (8.1.10) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.10)
- The inputSchema method now provides access to clientInput. (8.1.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/v8.1.0)

### Behavior and default changes

- Confirmed state uses successful action data when available, otherwise currentState; a revalidated currentState can supersede an in-flight dispatch result. (8.7.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.0)
- Validation and server errors roll back to the last confirmed domain state, and failed dispatches pass that state as prevResult.data to keep queued writes based. (8.7.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.0)
- useStateAction supports overlapping executeAsync invocations, with each promise settling with its own execution result. (8.6.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.0)
- SafeActionResult is now a discriminated union: checking data, serverError, or validationErrors narrows the other fields to undefined. (8.5.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.0)
- Structured inputs are now extracted from schemas instead of being derived by iterating client inputs. (8.1.4) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/v8.1.4)

### Fixes and other changes

- In useAction, useOptimisticAction, and useStateAction, onNavigation and onSettled now fire exactly once for a single redirect. (8.7.3) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.3)
- Stops leaking an unhandled promise rejection when the action call itself rejects; the error still reaches the caller through status, onError with thrownError, and the executeAsync rejection. (8.7.2) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.2)
- Stops leaking an unhandled promise rejection when the action call itself rejects; the error still reaches the caller through status, onError with thrownError, and the executeAsync rejection. (8.7.2) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.2)
- When currentState commits mid-queue, payloads from already-settled dispatches stop being applied again, preventing optimistic state from duplicating changes. (8.7.1) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.1)
- A currentState arriving while an action is running no longer discards that action’s data when building the next queued dispatch’s server base; the result follows write order. (8.7.1) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.1)
- A raw thrown error now settles promises for dispatches queued behind it; previously React clearing the action queue could leave those promises unresolved. (8.7.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.0)
- A throw from a dispatch made stale by reset no longer cancels fresh queued work. (8.7.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.0)
- A synchronous throw from a user callback no longer escapes before dispatch enqueueing, which could leave executeAsync pending forever. (8.7.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.7.0)
- When an action is dispatched inside a React transition, dispatch-time state now also applies from a microtask so it can commit immediately; this fixes pending status, input visibility, and callback timing in the action hooks. (8.6.1) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.1)
- Results resolving to undefined are normalized where stored, preventing onSuccess and onSettled from firing again on unrelated re-renders. (8.6.1) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.1)
- In useStateAction, reset() marks already-dispatched executions stale so they cannot clear reset state, consume the initResult baseline, or repopulate errors. (8.6.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.6.0)
- When called inside a Next.js 'use cache' scope with cacheComponents enabled, validation errors are returned as validationErrors instead of a generic server error. (8.5.5) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.5)
- Hook callbacks now fire once per action execution instead of replaying on every restore from the Next.js router bfcache. (8.5.4) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.5.4)
- The deprecation notice was removed from the hook. (8.3.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.3.0)
- The hook's code was fixed. (8.3.0) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.3.0)
- Reverses the `_errors`/object check order and skips `_errors` keys as nested objects. (8.1.9) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.9)
- Rapid execute or executeAsync calls now update UI state only from the latest request, preventing a slower earlier response from overwriting a later result; pre-transition state updates are synchronous. (8.1.9) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/next-safe-action%408.1.9)
- Checks ActionServerValidationError before the serverErrorHandled guard. (8.1.5) — [release notes](https://github.com/next-safe-action/next-safe-action/releases/tag/v8.1.5)
