{"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":58,"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":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/actions/runtime/server.ts#L40-L76","documentation":"Every server action runs its handler with `this` bound to an ActionAPIContext (marked internally by ACTION_API_CONTEXT_SYMBOL and containing params/cookies/locals). The runtime verifies that binding before executing; if the function is invoked with a wrong or missing `this` — typically a detached reference called as a bare function in server code — the check fails and ActionCalledFromServerError is thrown.","triggerScenarios":"Destructuring or aliasing an action then calling it as a plain function in server code: `const buy = actions.buy; await buy(input)`. Calling the raw handler exported from the actions module directly instead of through the proxy / Astro.callAction.","commonSituations":"Passing actions.myAction as a callback (e.g. to Promise.all or an event pipeline) which drops the receiver; refactoring imports to pull individual handlers out of the actions object; mixing client-call style into server code.","solutions":["Call actions in server code through the full path inside Astro.callAction: await Astro.callAction(actions.buy)(input)","When passing an action as a callback, pass a closure: (input) => Astro.callAction(actions.buy)(input)","Never import the handler directly from src/actions internals — always go through the actions proxy"],"exampleFix":"// before — server code\nconst { buy } = actions;\nawait buy(input); // lost receiver -> throws\n\n// after\nawait Astro.callAction(actions.buy)(input);","handlingStrategy":"validation","validationCode":"// keep the receiver attached when actions must be passed around\nconst runBuy = (input: BuyInput) => Astro.callAction(actions.buy)(input);\n// later: await runBuy(input) — closure preserves context binding","typeGuard":null,"tryCatchPattern":"try {\n  await buyRef(input); // a detached action reference\n} catch (e) {\n  if (e instanceof AstroError && e.code === 'ActionCalledFromServerError') {\n    // replace with Astro.callAction(actions.buy)(input)\n  } else throw e;\n}","preventionTips":["Never destructure actions out of the actions object in server code","Pass closures that call actions through Astro.callAction, not raw handler references","Centralize server-side action calls in one helper module to enforce the pattern"],"tags":["astro-actions","this-binding","callaction","ssr"],"backgroundTag":"missing-request-context","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}