{"record":{"id":"2655d3052aca383a","repo":"withastro/astro","slug":"internal-server-error","errorCode":"INTERNAL_SERVER_ERROR","errorMessage":"e instanceof Error ? e.message : 'Unknown error'","messagePattern":"e instanceof Error \\? e\\.message : 'Unknown error'","errorType":"error_code","errorClass":"ActionError","httpStatus":null,"severity":"error","filePath":"packages/astro/src/actions/runtime/server.ts","lineNumber":463,"sourceCode":"\t}\n\treturn schema;\n}\n\nasync function callSafely<TOutput>(\n\thandler: () => MaybePromise<TOutput>,\n): Promise<SafeResult<z.$ZodType, TOutput>> {\n\ttry {\n\t\tconst data = await handler();\n\t\treturn { data, error: undefined };\n\t} catch (e) {\n\t\tif (e instanceof ActionError) {\n\t\t\treturn { data: undefined, error: e };\n\t\t}\n\t\treturn {\n\t\t\tdata: undefined,\n\t\t\terror: new ActionError({\n\t\t\t\tmessage: e instanceof Error ? e.message : 'Unknown error',\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t}),\n\t\t};\n\t}\n}\n\nexport function serializeActionResult(res: SafeResult<any, any>): SerializedActionResult {\n\tif (res.error) {\n\t\tif (import.meta.env?.DEV) {\n\t\t\tactionResultErrorStack.set(res.error.stack);\n\t\t}\n\n\t\tlet body: Record<string, any>;\n\t\tif (res.error instanceof ActionInputError) {\n\t\t\tbody = {\n\t\t\t\ttype: res.error.type,\n\t\t\t\tissues: res.error.issues,\n\t\t\t\tfields: res.error.fields,\n\t\t\t};","sourceCodeStart":445,"sourceCodeEnd":481,"githubUrl":"https://github.com/withastro/astro/blob/52e6c34790cc8ac4e69e6135ace06049867e5c4a/packages/astro/src/actions/runtime/server.ts#L445-L481","documentation":"When an action handler throws anything that is not an `ActionError` (or `ActionInputError`), the runtime wraps it in a generic `ActionError` with `code: 'INTERNAL_SERVER_ERROR'`, preserving the original `e.message` (or 'Unknown error' for non-Error throws). This is the catch-all for unexpected bugs inside your action handler code.","triggerScenarios":"Any exception in the handler body: DB connection failures, `undefined is not a function` typos, failed `await context.locals` calls, third-party SDK errors, or throwing a plain string/object instead of an Error.","commonSituations":"Bugs in newly written handler logic; environment differences (missing env vars in prod); unhandled promise rejections from awaits inside the handler. The wrapper keeps the server from leaking stacks while still surfacing the message.","solutions":["Read the preserved message — it is the original error's text from inside your handler","Reproduce the handler logic directly (outside the action) or log at the throw site to get a stack","Convert expected failures into ActionError with a proper code so clients branch on it","Check env vars/services the handler depends on (DB URL, API keys) in the failing environment"],"exampleFix":"// before\nhandler: async (input) => {\n  const user = await db.user.findFirstOrThrow({ where: { id: input.id } }); // throws raw\n},\n\n// after\nimport { defineAction, ActionError } from 'astro:actions';\nhandler: async (input) => {\n  const user = await db.user.findFirst({ where: { id: input.id } });\n  if (!user) throw new ActionError({ code: 'NOT_FOUND', message: 'User not found' });\n  return user;\n},","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isActionError(e: unknown): e is ActionError {\n  return e instanceof ActionError;\n}","tryCatchPattern":"const result = await actions.user.update.safe(input);\nif (result.error) {\n  switch (result.error.code) {\n    case 'INTERNAL_SERVER_ERROR':\n      // original bug inside the handler; log result.error.message and alert\n      break;\n    default:\n      throw result.error;\n  }\n}","preventionTips":["Use the .safe() variant to get typed errors instead of exceptions in callers","Throw ActionError with precise codes for expected failures; reserve INTERNAL_SERVER_ERROR for true bugs","Log inside handlers around risky awaits (DB, fetch) to capture stacks the wrapper hides"],"tags":["actions","internal-error","error-handling","server"],"backgroundTag":"unhandled-server-exception","analyzedSha":"52e6c34790cc8ac4e69e6135ace06049867e5c4a","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}