{"record":{"id":"d72a39132779f2b1","repo":"mastra-ai/mastra","slug":"apierror-message-defaultmessage","errorCode":null,"errorMessage":"apiError.message || defaultMessage","messagePattern":"apiError\\.message \\|\\| defaultMessage","errorType":"http","errorClass":"HTTPException","httpStatus":500,"severity":"error","filePath":"packages/deployer/src/server/handlers/error.ts","lineNumber":10,"sourceCode":"import type { Context } from 'hono';\nimport { HTTPException } from 'hono/http-exception';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\n\nimport type { ApiError } from '../types';\n\n// Helper to handle errors consistently\nexport function handleError(error: unknown, defaultMessage: string): Promise<Response> {\n  const apiError = error as ApiError;\n  throw new HTTPException((apiError.status || 500) as ContentfulStatusCode, {\n    message: apiError.message || defaultMessage,\n    cause: apiError.cause,\n  });\n}\nexport function errorHandler(err: Error, c: Context, isDev?: boolean): Response {\n  if (err instanceof HTTPException) {\n    if (isDev) {\n      return c.json({ error: err.message, cause: err.cause, stack: err.stack }, err.status);\n    }\n    return c.json({ error: err.message }, err.status);\n  }\n\n  c.get('mastra').getLogger().error(err);\n  return c.json({ error: 'Internal Server Error' }, 500);\n}\n","sourceCodeStart":1,"sourceCodeEnd":26,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/deployer/src/server/handlers/error.ts#L1-L26","documentation":"handleError normalizes any thrown value in a server handler into an HTTPException. It casts the error to ApiError and uses its message, falling back to the defaultMessage passed by the caller; the resulting message shown is apiError.message || defaultMessage with status defaulting to 500. This is the deployer server's consistent error translation layer.","triggerScenarios":"Any handler (e.g. restartAllActiveWorkflowRunsHandler) throws a non-HTTP error, or throws an object without a message/status; handleError converts it — with status undefined becoming 500 and message undefined becoming the handler's defaultMessage.","commonSituations":"Workflow restart fails because the workflow run no longer exists in storage; storage/connection errors inside handlers; an error thrown without a message property reaching the API surface as a 500.","solutions":["Inspect the response body message: if it is the defaultMessage, the original error had no message — check server logs for the real cause.","For restart endpoints, verify the workflow run id exists and storage is reachable before retrying.","Throw typed ApiError-shaped errors (with status and message) from custom handlers to control the returned status code."],"exampleFix":"// before\nthrow new Error(); // no message -> 500 + defaultMessage\n// after\nthrow Object.assign(new Error('Workflow run not found'), { status: 404 });","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"function isApiError(e: unknown): e is { status?: number; message?: string; cause?: unknown } {\n  return typeof e === 'object' && e !== null && ('status' in e || 'message' in e);\n}","tryCatchPattern":"try {\n  const res = await fetch('/api/workflows/runs/restart', { method: 'POST', body });\n  if (!res.ok) {\n    const { message } = await res.json();\n    throw new Error(message || `Request failed with ${res.status}`);\n  }\n} catch (e) {\n  if (e instanceof HTTPException) {\n    console.error(`Server error ${e.status}: ${e.message}`);\n  }\n  throw e;\n}","preventionTips":["Throw errors with explicit status and message properties in custom handlers","Log the cause server-side; the client may only see the defaultMessage","Check storage connectivity when restart/run endpoints return 500"],"tags":["server","http","error-handling","hono"],"backgroundTag":"unhandled-server-error-500","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}