{"record":{"id":"14f3ec11b7f78149","repo":"withastro/astro","slug":"astro-actions-getactioncontext-unexpectedly","errorCode":null,"errorMessage":"[astro:actions] `getActionContext()` unexpectedly used on the client.","messagePattern":"\\[astro:actions\\] `getActionContext\\(\\)` unexpectedly used on the client\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/actions/runtime/entrypoints/client.ts","lineNumber":32,"sourceCode":"\tActionError,\n\tisActionError,\n\tisInputError,\n} from '../client.js';\nexport type {\n\tActionAPIContext,\n\tActionClient,\n\tActionErrorCode,\n\tActionInputSchema,\n\tActionReturnType,\n\tSafeResult,\n} from '../types.js';\n\nexport function defineAction() {\n\tthrow new Error('[astro:actions] `defineAction()` unexpectedly used on the client.');\n}\n\nexport function getActionContext() {\n\tthrow new Error('[astro:actions] `getActionContext()` unexpectedly used on the client.');\n}\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) => {\n\t\tconst headers = new Headers();\n\t\theaders.set('Accept', 'application/json');\n\t\t// Apply adapter-specific headers for internal fetches\n\t\tfor (const [key, value] of Object.entries(internalFetchHeaders)) {\n\t\t\theaders.set(key, value);\n\t\t}\n\t\tlet body = param;\n\t\tif (!(body instanceof FormData)) {\n\t\t\ttry {","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/actions/runtime/entrypoints/client.ts#L14-L50","documentation":"getActionContext() reads per-request state (locals, params, cookies, the action's name and calledFrom mode) and therefore only exists during server request handling. The client build of astro:actions replaces it with a throwing stub, so any browser-side execution fails with this message instead of silently returning an unusable context.","triggerScenarios":"Calling getActionContext() inside a <script>, a client-side framework component, or any module that only runs in the browser. Importing server runtime code (e.g. from astro:actions/server.js or a file that calls getActionContext) into a client bundle.","commonSituations":"Copying middleware-style context code into a client component; sharing a utility that reads action context between server and client files; importing an Astro page module's helper into client code.","solutions":["Keep getActionContext() calls in server-only files: actions handlers, .astro frontmatter, API endpoints, middleware","Pass whatever data the client needs (action name, result) down as props instead of reading context in the browser","If a shared module must branch, guard with if (import.meta.env.SSR) before calling it"],"exampleFix":"// before — src/components/Status.jsx (client:load)\nimport { getActionContext } from 'astro:actions';\nconst ctx = getActionContext(Astro); // browser -> throws\n\n// after — pass data from the server page\n// Astro page (server):\nconst ctx = getActionContext(Astro);\n---\n// src/components/Status.jsx (client)\nexport default function Status({ actionName }) { return <p>{actionName}</p>; }","handlingStrategy":"validation","validationCode":"// branch on environment before touching server-only APIs\nif (import.meta.env.SSR) {\n  const ctx = getActionContext(Astro);\n  // use ctx safely\n} else {\n  // derive equivalent data from props/state in the browser\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat getActionContext as server-only API: only call it in handlers, pages, endpoints, middleware","Pass request-derived data to client components as props rather than reading context there","Name server-only files clearly (e.g. *.server.ts) so they are never imported into browser bundles"],"tags":["astro-actions","ssr","client-bundle","request-context"],"backgroundTag":"server-code-in-client-bundle","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"}