{"record":{"id":"157518ab28c2351d","repo":"withastro/astro","slug":"actioncalledfromservererror-157518","errorCode":"ActionCalledFromServerError","errorMessage":"Action called from a server-rendered page or endpoint without using `Astro.callAction()`. This wrapper must be used to call actions from server code.","messagePattern":"Action called from a server-rendered page or endpoint without using `Astro\\.callAction\\(\\)`\\. This wrapper must be used to call actions from server code\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/actions/runtime/server.ts","lineNumber":57,"sourceCode":"\t\t: undefined,\n>({\n\taccept,\n\tinput: inputSchema,\n\thandler,\n}: {\n\tinput?: TInputSchema;\n\taccept?: TAccept;\n\thandler: ActionHandler<TInputSchema, TOutput>;\n}): ActionClient<TOutput, TAccept, TInputSchema> & string {\n\tconst serverHandler =\n\t\taccept === 'form'\n\t\t\t? getFormServerHandler(handler, inputSchema)\n\t\t\t: getJsonServerHandler(handler, inputSchema);\n\n\tasync function safeServerHandler(this: ActionAPIContext, unparsedInput: unknown) {\n\t\t// The ActionAPIContext should always contain the `params` property\n\t\tif (typeof this === 'function' || !isActionAPIContext(this)) {\n\t\t\tthrow new AstroError(ActionCalledFromServerError);\n\t\t}\n\t\treturn callSafely(() => serverHandler(unparsedInput, this));\n\t}\n\n\tObject.assign(safeServerHandler, {\n\t\torThrow(this: ActionAPIContext, unparsedInput: unknown) {\n\t\t\tif (typeof this === 'function') {\n\t\t\t\tthrow new AstroError(ActionCalledFromServerError);\n\t\t\t}\n\t\t\treturn serverHandler(unparsedInput, this);\n\t\t},\n\t});\n\n\treturn safeServerHandler as ActionClient<TOutput, TAccept, TInputSchema> & string;\n}\n\nfunction getFormServerHandler<TOutput, TInputSchema extends z.$ZodType>(\n\thandler: ActionHandler<TInputSchema, TOutput>,","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/astro/src/actions/runtime/server.ts#L39-L75","documentation":"Inside defineAction(), the wrapped safeServerHandler verifies its this binding is a genuine ActionAPIContext (carrying ACTION_API_CONTEXT_SYMBOL). If this is a plain function or lacks the symbol, AstroError ActionCalledFromServerError is thrown. This guards the handler from being invoked as a bare reference instead of through Astro.callAction().","triggerScenarios":"Destructuring an action and calling it directly (await myAction(input)) on the server, or passing the action reference as a callback and then invoking it, so this is undefined/not the Astro context.","commonSituations":"Server code that treats the action like an ordinary async function; passing actions.foo into a utility that calls it; calling from a non-Astro module where no context is bound.","solutions":["Always call via Astro.callAction(actions.myAction, input) on the server.","Do not invoke the action reference directly; do not pass it as a detached callback.","If you need the logic elsewhere, extract a plain function and call that from both the handler and the other site."],"exampleFix":"// before\nimport { actions } from './actions';\nconst { myAction } = actions;\nconst result = await myAction(input);\n// after\nconst result = await Astro.callAction(actions.myAction, input);","handlingStrategy":"validation","validationCode":"// Disallow calling action references directly; route all server calls through Astro.callAction.\n// Static lint rule (conceptual): flag any `await someAction(` that is not preceded by Astro.callAction.\n// Example runtime helper used in server code:\nasync function serverCall<T>(astro: any, fn: Function, input: unknown): Promise<T> {\n  if (typeof astro?.callAction !== 'function') throw new Error('Use Astro.callAction on the server');\n  return astro.callAction(fn, input);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never destructure and call actions on the server; use Astro.callAction().","Do not pass action references as detached callbacks.","Extract reusable logic into plain functions called by both handler and other code."],"tags":["actions","server","callaction","context-binding"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}