{"record":{"id":"75dc6c2ed1f4be54","repo":"withastro/astro","slug":"actioncalledfromservererror","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/entrypoints/server.ts","lineNumber":36,"sourceCode":"\tActionInputSchema,\n\tActionReturnType,\n\tSafeResult,\n} from '../types.js';\n\nexport const getActionPath = createGetActionPath({\n\tbaseUrl: import.meta.env.BASE_URL,\n\tshouldAppendTrailingSlash,\n});\n\nexport const actions = createActionsProxy({\n\thandleAction: async (param, path, context) => {\n\t\tconst state: FetchState | undefined = context\n\t\t\t? Reflect.get(context, fetchStateSymbol)\n\t\t\t: undefined;\n\t\tif (!state) {\n\t\t\t// The context was not created by Astro's request handling (e.g.\n\t\t\t// an action invoked from server code without a context).\n\t\t\tthrow new AstroError(ActionCalledFromServerError);\n\t\t}\n\t\tconst action = await getAction(state.manifest, path);\n\t\tif (!action) throw new Error(`Action not found: ${path}`);\n\t\treturn action.bind(context)(param);\n\t},\n});\n","sourceCodeStart":18,"sourceCodeEnd":43,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/actions/runtime/entrypoints/server.ts#L18-L43","documentation":"The server-side actions proxy requires per-request state (the SSR manifest and current context) which Astro attaches via an internal fetch-state symbol during request handling. When an action is invoked in server code outside that flow — directly in a page or endpoint body — the state is absent, so Astro throws ActionCalledFromServerError telling you to route the call through Astro.callAction().","triggerScenarios":"Calling actions.myAction(input) directly in .astro frontmatter or in an API endpoint without the wrapper; invoking the server actions proxy from code that runs outside a request (module scope, background job) where no Astro context exists.","commonSituations":"Porting client-style action calls into a page; calling actions during prerender/module evaluation; calling an action inside an endpoint to reuse logic instead of extracting the handler.","solutions":["Wrap server-side calls: const result = await Astro.callAction(actions.myAction)(input)","If you need the logic outside a request, extract a plain function and have both the action handler and the caller use it","Make sure the file executing the call receives the Astro context (a page/endpoint), not a detached module"],"exampleFix":"// before — src/pages/dashboard.astro frontmatter\nconst result = await actions.getUser(userId); // throws\n\n// after\nconst result = await Astro.callAction(actions.getUser)(userId);","handlingStrategy":"validation","validationCode":"// normalize server-side calls through one helper so context is never missing\nexport async function callFromServer<A extends (input: never) => Promise<unknown>>(\n  Astro: AstroGlobal,\n  action: A,\n  input: Parameters<A>[0],\n) {\n  if (!Astro?.callAction) throw new Error('Not in an Astro request scope');\n  return Astro.callAction(action)(input);\n}","typeGuard":"function hasCallAction(astro: unknown): astro is AstroGlobal {\n  return typeof astro === 'object' && astro !== null && typeof (astro as AstroGlobal).callAction === 'function';\n}","tryCatchPattern":"try {\n  const r = await actions.getUser(id);\n} catch (e) {\n  if (e instanceof AstroError && e.code === 'ActionCalledFromServerError') {\n    // re-route through: await Astro.callAction(actions.getUser)(id)\n  } else throw e;\n}","preventionTips":["In any server file, always call actions via Astro.callAction(actions.name)(input)","Never call actions at module scope or outside the request lifecycle; extract shared logic into plain functions instead","Code-review for bare `actions.` calls in .astro frontmatter and endpoints"],"tags":["astro-actions","ssr","callaction","request-context"],"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"}