#Call actions using their names

1 messages · Page 1 of 1 (latest)

trim jackal
#

Can we call convex actions, mutations, etc using their names rather than the generated code ?

frank ironBOT
#

Hi @trim jackal. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Short answer: No — Convex is designed for you to call functions via the generated api/internal references, not by string names.

  • Public and internal functions are exposed as typed endpoints through the generated api (and internal) objects; clients and server code call them via these references (for example, React’s useMutation/useAction with api functions, server ctx.runMutation with internal functions) (Calling mutations from clients, Calling actions from clients, Internal functions).
  • This approach enforces validation, transaction semantics, access control (public vs internal), and end-to-end type safety. Calling functions “by name” is discouraged and considered an anti-pattern; the exports in /convex are API endpoints you invoke through the generated references, not arbitrary callables by string key (Discord: anti-pattern discussion, Discord: separation of exposure vs model).
  • In tests, you likewise call them via t.query/t.mutation/t.action with api/internal references, not names (convex-test).
#

If you’re looking to avoid importing many individual functions, you can organize and re-export modules (e.g., barrel files) but you still call through api/internal, not by string name (Discord: code organization tip).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@trim jackal Kapa.ai is still learning and improving, please let me know how I did by reacting below.

trim jackal
#

@frank iron But i have saw in the code of an official convex package doing context.runAction("auth:...", ....)

frank ironBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

You’re right that there are cases showing actions run “by name.” Two clarifications:

  • In the browser/client, BaseConvexClient.action(name, args) accepts a string name: this is the public client API to execute an action by its name (e.g., "module:function"). It returns a Promise of the action’s result (this is for clients, not server code) (BaseConvexClient.action).

  • On the server, inside an action, ctx.runAction exists and can call another action. However, best practice is to avoid runAction unless you’re crossing runtimes (Convex runtime -> Node.js runtime); otherwise extract shared code into a helper instead of nesting actions. Also, prefer calling internal functions via internal references rather than names for type-safety and security (GenericActionCtx methods, Use runAction only when using a different runtime, Only schedule and ctx.run* internal functions).

There’s also an advanced pattern in community content that builds a retrier which schedules actions by constructing a function reference from a string name (makeFunctionReference<"action">(name))—useful, but note the warnings about exposure and that it’s done via scheduler, not direct invocation (Retry actions: how it works).

#

So:

  • Clients can call actions by name via the client API.
  • Server code should prefer internal function references; use ctx.runAction sparingly, mainly for cross-runtime needs.

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@trim jackal Kapa.ai is still learning and improving, please let me know how I did by reacting below.

trim jackal
#

@frank iron can i use the function definition as a reference ?

frank ironBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

Short answer: not directly. You should pass Convex function references (from the generated api/internal objects) or construct one explicitly, not the raw function definition.

Calling the exported function directly is an anti-pattern because it bypasses argument validation and transactional/isolated execution; always invoke through the Convex function reference mechanisms (Discord discussion: anti-pattern).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:

#

@trim jackal Kapa.ai is still learning and improving, please let me know how I did by reacting below.

trim jackal
#

@frank iron the thing is that i don't use codegen because am building a reusable library and i don't have an exact path because again am building a library so ican't use the path or anyApi. How do i do ? how is createFunctionHandle used ?

frank ironBOT
#

Let me check the knowledge base for you again. One moment! :books:

#

If you’re not using codegen, you can still work with function references and handles without hardcoding paths:

  • Build a FunctionReference from a string name at runtime with makeFunctionReference. The name format is "dir/module:export" (e.g., "auth/login:perform"). This returns a typed FunctionReference you can pass to clients, ctx.run*, or schedulers (makeFunctionReference docs; query name format) (makeFunctionReference, Query names).

  • If you need a serializable handle (for components/scheduling across pushes), create one from a FunctionReference using createFunctionHandle, which yields a FunctionHandle you can store/pass around. Note this API is for Components and marked unstable (createFunctionHandle; FunctionHandle) (createFunctionHandle, FunctionHandle).

Example (no codegen, dynamic name):

import { makeFunctionReference } from "convex/server";

// Build a reference from a string assembled by your library
const ref = makeFunctionReference<"action">(runtimeNameString);

// Use with ctx.runAction / scheduler / clients, etc.
// e.g., inside an action:
// await ctx.runAction(ref, args);

If you have a FunctionReference and want its address parts, server utilities exist:

  • getFunctionName(functionReference) gives "dir/module:export" (useful for logging or serialization) (getFunctionName).
  • getFunctionAddress can expose handle/name/reference forms used by Components (advanced) (getFunctionAddress).
#

Notes:


Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: