{"record":{"id":"0411a04449a7e99f","repo":"trpc/trpc","slug":"bad-request-0411a0","errorCode":"BAD_REQUEST","errorMessage":"Invalid input","messagePattern":"Invalid input","errorType":"error_code","errorClass":"TRPCError","httpStatus":400,"severity":"error","filePath":"packages/server/src/unstable-core-do-not-import/http/contentType.ts","lineNumber":57,"sourceCode":"function memo<TReturn>(fn: () => Promise<TReturn>) {\n  let promise: Promise<TReturn> | null = null;\n  const sym = Symbol.for('@trpc/server/http/memo');\n  let value: TReturn | typeof sym = sym;\n  return {\n    /**\n     * Lazily read the value\n     */\n    read: async (): Promise<TReturn> => {\n      if (value !== sym) {\n        return value;\n      }\n\n      // dedupes promises and catches errors\n      promise ??= fn().catch((cause) => {\n        if (cause instanceof TRPCError) {\n          throw cause;\n        }\n        throw new TRPCError({\n          code: 'BAD_REQUEST',\n          message: cause instanceof Error ? cause.message : 'Invalid input',\n          cause,\n        });\n      });\n\n      value = await promise;\n      promise = null;\n\n      return value;\n    },\n    /**\n     * Get an already stored result\n     */\n    result: (): TReturn | undefined => {\n      return value !== sym ? value : undefined;\n    },\n  };","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/trpc/trpc/blob/acff82332de8b4562d3e6975fa8d94ab1a6de5e0/packages/server/src/unstable-core-do-not-import/http/contentType.ts#L39-L75","documentation":"This is the generic catch-all inside the content-type `memo().read()` used for input parsing. Any non-TRPCError thrown while reading or deserializing input (e.g. `req.json()` failing, or the transformer's `deserialize` throwing) is rethrown as BAD_REQUEST with the original cause preserved; existing TRPCErrors pass through unchanged.","triggerScenarios":"A malformed JSON body; a superjson transformer failing to deserialize a value whose custom type is not registered; a custom transformer throwing on unexpected input.","commonSituations":"Client forgot to register a custom Superjson type on the server; client sent values like unregistered dates/classes; transformer version skew between client and server.","solutions":["Inspect `error.cause` (and `error.data.cause`) for the real underlying reason.","Ensure transformer type registration matches exactly on client and server.","Validate the payload shape on the client before sending, and surface transformer errors clearly during development."],"exampleFix":"// before - superjson custom type registered only on client\n// client:  superjson.registerCustom(MyDate, 'date')\n// server:  (missing)\n\n// after - register on BOTH sides, shared module\n// shared/registry.ts\nexport const s = SuperJSON;\ns.registerCustom(Date, (v) => v.toISOString(), (v) => new Date(v));\n// import { s } from '../shared/registry' on both client and server","handlingStrategy":"try-catch","validationCode":"// Validate the body parses with the configured transformer before sending\nimport { transformer } from '../shared/transformer';\nfunction safeSerialize(value: unknown): string {\n  const wire = transformer.input.serialize(value);\n  return JSON.stringify(wire); // throws here if the type is unregistered\n}","typeGuard":"function isTransformerRegistered(\n  transformer: { input: { serialize: (x: unknown) => unknown } },\n  sample: unknown,\n): boolean {\n  try { transformer.input.serialize(sample); return true; } catch { return false; }\n}","tryCatchPattern":"try {\n  await trpc.proc.query(input);\n} catch (e) {\n  if (e instanceof TRPCError && e.code === 'BAD_REQUEST' && /Invalid input/.test(e.message)) {\n    // Inspect e.cause: usually JSON.parse or transformer.deserialize failed\n  }\n  throw e;\n}","preventionTips":["Register all custom transformer types identically on client and server.","Share the transformer/registry module between both sides.","Surface `error.cause` in dev logging to catch the real deserialize failure."],"tags":["input-parsing","transformer","validation","http"],"backgroundTag":null,"analyzedSha":"acff82332de8b4562d3e6975fa8d94ab1a6de5e0","analyzedAt":"2026-08-12T22:04:41.179Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}