{"record":{"id":"b0c27a7a02ccf3e5","repo":"trpc/trpc","slug":"greeting-not-found","errorCode":null,"errorMessage":"Greeting not found","messagePattern":"Greeting not found","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"www/versioned_docs/version-9.x/server/output-validation.md","lineNumber":102,"sourceCode":"});\n\nexport type AppRouter = typeof appRouter;\n```\n\n### With custom validator\n\n```tsx\nimport * as trpc from '@trpc/server';\nimport * as t from 'superstruct';\n\n// [...]\n\nexport const appRouter = trpc.router<Context>().query('hello', {\n  output: (value: any) => {\n    if (value && typeof value.greeting === 'string') {\n      return { greeting: value.greeting };\n    }\n    throw new Error('Greeting not found');\n  },\n  // expects return type of { greeting: string }\n  resolve() {\n    return { greeting: 'hello!' };\n  },\n});\n\nexport type AppRouter = typeof appRouter;\n```\n","sourceCodeStart":84,"sourceCodeEnd":112,"githubUrl":"https://github.com/trpc/trpc/blob/acff82332de8b4562d3e6975fa8d94ab1a6de5e0/www/versioned_docs/version-9.x/server/output-validation.md#L84-L112","documentation":"A documentation example (output-validation.md, v9) using tRPC v9's router().query() API with a custom output validator. It throws 'Greeting not found' when the returned value does not have a string greeting property, showing how to validate resolver output in tRPC v9 before schema libraries were the default.","triggerScenarios":"The hello resolver returns a value without a string greeting property (e.g. null, {}, { greeting: 123 }), so the output validator throws.","commonSituations":"Resolver return shape drifting from the validator; migrating from v9 and forgetting to update the output check; returning undefined from resolve().","solutions":["Ensure resolve() returns { greeting: string }.","Replace the custom validator with a zod/superstruct schema for the output.","Update the validator if the resolver contract intentionally changed."],"exampleFix":"// before: resolver returns wrong shape\nresolve() { return { message: 'hi' }; }\n// after: match the validated shape\nresolve() { return { greeting: 'hello!' }; }","handlingStrategy":"validation","validationCode":"// Validate the resolver output before relying on it\nfunction hasGreeting(v: unknown): boolean {\n  return typeof v === 'object' && v !== null && typeof (v as any).greeting === 'string';\n}","typeGuard":"function isGreetingObj(v: unknown): v is { greeting: string } {\n  return typeof v === 'object' && v !== null && typeof (v as any).greeting === 'string';\n}","tryCatchPattern":null,"preventionTips":["Use zod/superstruct for output in v9 to align types and validation.","Unit-test the resolver against the output contract.","Migrate custom output validators to schemas when upgrading."],"tags":["validation","output","v9","docs-example"],"backgroundTag":null,"analyzedSha":"acff82332de8b4562d3e6975fa8d94ab1a6de5e0","analyzedAt":"2026-08-12T22:04:41.179Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}