Safe Action Advanced
Use when working with bind arguments, metadata schemas, framework errors (redirect/notFound/forbidden/unauthorized), type inference utilities (InferSafeActionFnInput/Result), or server-level action callbacks
- Skill ID
- next-safe-action/skills/safe-action-advanced
- Publisher
- next-safe-action
- Repository
- skills
- Installs
- 0
- Files
- 5
- Synced
- Sep 23, 2026
Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.
next-safe-action/skills/safe-action-advancedInstalls these files- SKILL.md
- bind-arguments.md
- framework-errors.md
- metadata.md
- type-utilities.md
What this skill tells the agent
next-safe-action Advanced Features
Overview
| Feature | Use Case |
|---|---|
| Bind arguments | Pass extra args to actions via .bind() (e.g., resource IDs) |
| Metadata | Attach typed metadata to actions for use in middleware |
| Framework errors | Handle redirect, notFound, forbidden, unauthorized in actions |
| Type utilities | Infer types from action functions and middleware |
Server-Level Action Callbacks
The second argument to .action() accepts callbacks that run on the server (not client-side hooks):
export const createPost = authActionClient
.inputSchema(schema)
.action(
async ({ parsedInput, ctx }) => {
const post = await db.post.create(parsedInput);
return post;
},
{
onSuccess: async ({ data, parsedInput, ctx, metadata, clientInput }) => {
// Runs on the server after successful execution
await invalidateCache("posts");
},
onError: async ({ error, metadata, ctx, clientInput, bindArgsClientInputs }) => {
// error: { serverError?, validationErrors? }
await logError(error);
},
onSettled: async ({ result }) => {
// Always runs
await recordMetrics(result);
},
onNavigation: async ({ navigationKind }) => {
// Runs when a framework error (redirect, notFound, etc.) occurs
console.log("Navigation:", navigationKind);
},
}
);These are distinct from hook callbacks (useAction({ onSuccess })) — server callbacks run in the Node.js runtime, hook callbacks run in the browser.
throwServerError
Re-throw server errors instead of returning them as result.serverError:
export const myAction = actionClient
.inputSchema(schema)
.action(serverCodeFn, {
throwServerError: true,
// The handled server error (return of handleServerError) is thrown
});Don't confuse this with returnServerError(): throwServerError throws the handled error (post-handleServerError) instead of returning it, while returnServerError(payload) returns a typed expected error in result.serverError, bypassing handleServerError entirely (see the safe-action-client skill's error-handling doc).
More from next-safe-action
Use this skill in a project
Open any RiverX project, search the Skills panel for next-safe-action/skills/safe-action-advanced, and install it in one click.
