{"record":{"id":"2875fe82b4211a28","repo":"withastro/astro","slug":"getactionstate-could-not-find-a-state-object","errorCode":null,"errorMessage":"`getActionState()` could not find a state object.","messagePattern":"`getActionState\\(\\)` could not find a state object\\.","errorType":"exception","errorClass":"AstroError","httpStatus":null,"severity":"error","filePath":"packages/integrations/react/src/actions.ts","lineNumber":58,"sourceCode":"\treturn callback;\n}\n\n/**\n * Retrieve the state object from your action handler when using `useActionState()`.\n * To ensure this state is retrievable, use the {@linkcode withState} helper.\n */\nexport async function getActionState<T>({ request }: { request: Request }): Promise<T> {\n\tconst contentType = request.headers.get('Content-Type');\n\tif (!contentType || !isFormRequest(contentType)) {\n\t\tthrow new AstroError(\n\t\t\t'`getActionState()` must be called with a form request.',\n\t\t\t\"Ensure your action uses the `accept: 'form'` option.\",\n\t\t);\n\t}\n\tconst formData = await request.clone().formData();\n\tconst state = formData.get('_astroActionState')?.toString();\n\tif (!state) {\n\t\tthrow new AstroError(\n\t\t\t'`getActionState()` could not find a state object.',\n\t\t\t'Ensure your action was passed to `useActionState()` with the `withState()` wrapper.',\n\t\t);\n\t}\n\treturn JSON.parse(state) as T;\n}\n\nconst formContentTypes = ['application/x-www-form-urlencoded', 'multipart/form-data'];\n\nfunction isFormRequest(contentType: string) {\n\t// Split off parameters like charset or boundary\n\t// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type#content-type_in_html_forms\n\tconst type = contentType.split(';')[0].toLowerCase();\n\n\treturn formContentTypes.some((t) => type === t);\n}\n\n/**","sourceCodeStart":40,"sourceCodeEnd":76,"githubUrl":"https://github.com/withastro/astro/blob/d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca/packages/integrations/react/src/actions.ts#L40-L76","documentation":"Thrown by @astrojs/react's `getActionState()` when the form request is valid but the `_astroActionState` field is absent from the parsed `FormData`. That field is injected by the `withState()` wrapper so the server can recover the prior state passed to `useActionState()`.","triggerScenarios":"Calling `getActionState` on an action that was NOT wrapped with `withState()` before being passed to React's `useActionState()`. A hand-built form that posts to the action without the hidden `_astroActionState` input. The wrapper's `formData.set('_astroActionState', ...)` was skipped because the callback branch returned early.","commonSituations":"Passing the raw action to `useActionState` instead of `withState(action)`. Using a custom form submission that bypasses React's progressive-enhancement hidden field injection.","solutions":["Wrap the action with `withState()` before handing it to `useActionState()`: `const [state, dispatch] = useActionState(withState(myAction), initial);`.","Confirm the action is invoked through the wrapper, not the original function reference.","If posting manually, include a `_astroActionState` field (JSON-stringified state) in the FormData."],"exampleFix":"// before\nconst [state, dispatch] = useActionState(myAction, initialState);\n// after\nimport { withState } from '@astrojs/react/actions';\nconst [state, dispatch] = useActionState(withState(myAction), initialState);","handlingStrategy":"validation","validationCode":"const formData = await request.clone().formData();\nif (!formData.has('_astroActionState')) {\n  throw new Error('Action not wired through withState(); skipping getActionState.');\n}","typeGuard":null,"tryCatchPattern":"try { const state = await getActionState({ request }); } catch (e) { if (/could not find a state object/) { /* return initial state */ } else throw e; }","preventionTips":["Always pass actions through `withState()` before `useActionState`.","Unit-test the action end-to-end with a real form post.","Document the requirement in the action's JSDoc."],"tags":["react","actions","useactionstate","forms"],"backgroundTag":null,"analyzedSha":"d081033d5fe8e8a68c4bbbad4af9d2deb9c74bca","analyzedAt":"2026-08-12T13:37:29.035Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}