next-safe-action/skills5 files

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

Specification
Skill ID
next-safe-action/skills/safe-action-advanced
Publisher
next-safe-action
Repository
skills
Installs
0
Files
5
Synced
Sep 23, 2026
How to use it

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

FeatureUse Case
Bind argumentsPass extra args to actions via .bind() (e.g., resource IDs)
MetadataAttach typed metadata to actions for use in middleware
Framework errorsHandle redirect, notFound, forbidden, unauthorized in actions
Type utilitiesInfer 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).

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.

Use this skill