@trpc/client
semver
>=10.0.0 <12.0.0postconditions4functions3last verified2026-06-24coverage score100%Postconditions: what we check
- query · trpc-query-missing-try-catcherrorWhenasync function calls a tRPC vanilla client .query() method without wrapping in try-catch. Throws TRPCClientError on network failures, HTTP errors, or server procedure errors (UNAUTHORIZED, NOT_FOUND, INTERNAL_SERVER_ERROR, TIMEOUT, TOO_MANY_REQUESTS).Throws
TRPCClientError — extends Error with shape, data (contains code, httpStatus), cause (original Error), and meta (response object). Wraps server-thrown TRPCError codes: UNAUTHORIZED (401), FORBIDDEN (403), NOT_FOUND (404), INTERNAL_SERVER_ERROR (500), TIMEOUT (408), TOO_MANY_REQUESTS (429), BAD_REQUEST (400).Required handlingCaller MUST wrap .query() in try-catch and handle TRPCClientError. Use isTRPCClientError(cause) to narrow the type. Minimum handling: try { const result = await trpc.someRoute.query(input); } catch (cause) { if (isTRPCClientError(cause)) { console.error('tRPC error:', cause.data?.code, cause.message); } throw cause; }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - mutate · trpc-mutate-missing-try-catcherrorWhenasync function calls a tRPC vanilla client .mutate() method without wrapping in try-catch. Throws TRPCClientError on network failures, HTTP errors, or server procedure errors (UNAUTHORIZED, NOT_FOUND, INTERNAL_SERVER_ERROR, CONFLICT, UNPROCESSABLE_CONTENT, etc.).Throws
TRPCClientError — extends Error with shape, data (contains code, httpStatus), cause (original Error), and meta (response object). Mutation errors include UNAUTHORIZED (401), CONFLICT (409), UNPROCESSABLE_CONTENT (422), INTERNAL_SERVER_ERROR (500), BAD_REQUEST (400 — failed input validation).Required handlingCaller MUST wrap .mutate() in try-catch and handle TRPCClientError. Minimum handling: try { const result = await trpc.someRoute.mutate(input); } catch (cause) { if (isTRPCClientError(cause)) { if (cause.data?.code === 'UNAUTHORIZED') { // redirect to login } console.error('Mutation failed:', cause.message); } throw cause; }costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible - subscribe · trpc-subscribe-missing-on-errorerrorWhenasync function calls a tRPC vanilla client .subscribe() method without providing an onError callback in the options object. All subscription errors (network disconnect, server TRPCError, UNAUTHORIZED, WebSocket close via TRPCWebSocketClosedError) are silently dropped — the internal error path is opts.onError?.(err), which is a no-op when the callback is absent.Throws
TRPCClientError — dispatched via onError callback, NOT thrown into calling code. Error is silently dropped when onError is absent. Error codes covered: UNAUTHORIZED (401), FORBIDDEN (403), INTERNAL_SERVER_ERROR (500), TIMEOUT (408), SERVICE_UNAVAILABLE (503), BAD_REQUEST (400), and TRPCWebSocketClosedError when the underlying WebSocket connection closes during an active subscription.Required handlingCaller MUST provide onError in the subscribe() options object. Minimum handling: const sub = trpc.liveUpdates.subscribe(input, { onData(data) { // handle incoming data }, onError(cause) { if (isTRPCClientError(cause)) { if (cause.data?.code === 'UNAUTHORIZED') { // redirect to login or refresh auth } console.error('Subscription error:', cause.message); } }, onComplete() { // subscription ended normally }, });costmediumin prodsilent failureusers seelost datavisibilitysilent - subscribe · trpc-subscribe-auth-error-silenterrorWhentRPC subscription receives UNAUTHORIZED (401) or FORBIDDEN (403) from the server (token expired, session revoked, or permission change during an active real-time connection) but caller has no onError callback to detect the auth failure. The subscription is cancelled server-side and the client silently stops receiving data without any error signal.Throws
TRPCClientError with data.code = 'UNAUTHORIZED' or 'FORBIDDEN'. Dispatched via optional onError callback — silently dropped if absent.Required handlingCheck cause.data?.code in onError handler and redirect to login or refresh the auth token when 'UNAUTHORIZED' or 'FORBIDDEN' is received.costmediumin prodsilent failureusers seeauthentication failurevisibilitysilent
Sources
Every postcondition cites at least one of these. Grouped by source type; numbered to match the footnotes above.
Official documentation
- [1]trpc.io/docs/client/vanillaInfer Types
- [2]trpc.io/docs/server/error-handlingError Handling
- [4]trpc.io/docs/subscriptionsSubscriptions
Source code
- [3]github.com/trpc/trpc/blobtrpc/trpc · TRPCUntypedClient.ts
Research notes
Curator notes from SOURCES.md captured when the profile was written so you can verify the reasoning, not just the rules.
Sources — @trpc/client
Documentation Sources
| URL | Fetched | Summary |
|---|---|---|
| https://trpc.io/docs/client/vanilla | 2026-04-02 | Vanilla client overview |
| https://trpc.io/docs/client/vanilla/setup | 2026-04-02 | Client setup guide |
| https://trpc.io/docs/client/vanilla/infer-types | 2026-04-02 | Error handling pattern with isTRPCClientError |
| https://trpc.io/docs/server/error-handling | 2026-04-02 | TRPCError codes and error response structure |
| https://raw.githubusercontent.com/trpc/trpc/main/packages/client/src/TRPCClientError.ts | 2026-04-02 | TRPCClientError class definition |
Key Evidence
From https://trpc.io/docs/client/vanilla/infer-types:
The documented pattern for vanilla client error handling:
try { await trpc.post.byId.query('1'); } catch (cause) { if (isTRPCClientError(cause)) { console.log('data', cause.data); } }
From https://trpc.io/docs/server/error-handling:
tRPC defines error codes including UNAUTHORIZED (401), NOT_FOUND (404), INTERNAL_SERVER_ERROR (500). All procedure errors are wrapped in TRPCClientError on the client side.
Type Definition Source
Examined from installed package /tmp/trpc-examine/node_modules/@trpc/client/dist/:
index.d.mts— main exportstypes.d-CAr6snH0.d.mts— TRPCClientError class definition- Both
.query()and.mutate()returnPromise<output>and throwTRPCClientError
Need a different package?
Request a profile