calcom/cal.diy · error · TRPCError
${error.message as TRPCErrorCode}
Error message
${error.message as TRPCErrorCode} What it means
Re-thrown as a TRPCError whose code is the upstream error.message, but only when that message is a key present in TRPC_ERROR_MAP (i.e. a known tRPC error code). The slots controller bridges an underlying tRPC-layer error into the Nest response pipeline by mapping its textual code back into a structured TRPCError. If the message is not in the map, control falls through to the final `throw error`.
Source
Thrown at apps/api/v2/src/modules/slots/slots-2024-04-15/controllers/slots.controller.ts:223
query.timeZone
);
return {
data: {
slots,
},
status: SUCCESS_STATUS,
};
} catch (error) {
if (error instanceof Error) {
if (error.message.includes("Invalid time range given")) {
throw new BadRequestException(
"Invalid time range given - check the 'startTime' and 'endTime' query parameters."
);
}
if (TRPC_ERROR_MAP[error.message as keyof typeof TRPC_ERROR_CODE]) {
throw new TRPCError({ code: error.message as TRPCErrorCode });
}
}
throw error;
}
}
}
View on GitHub (pinned to 176037d0af)
Solutions
- Handle the upstream cause: a BAD_REQUEST means bad inputs, UNAUTHORIZED means auth — fix the triggering condition rather than the wrapper.
- If a legitimate new tRPC code is not in TRPC_ERROR_MAP, add it to the map so it translates instead of falling through to a raw 500.
- Catch TRPCError in your client and switch on error.code to drive UX.
Example fix
// before — new code thrown but not mapped, surfaces as raw error
// (TRPC_ERROR_MAP missing 'PAYLOAD_TOO_LARGE')
// after — extend the map
TRPC_ERROR_MAP = { ...TRPC_ERROR_MAP, PAYLOAD_TOO_LARGE: 'PAYLOAD_TOO_LARGE' } as const;
// client:
try { await api.getSlots(q); }
catch (e) { if (e.code === 'UNAUTHORIZED') redirectToLogin(); } Defensive patterns
Strategy: try-catch
Type guard
const isTrpcCode = (code: unknown): boolean => typeof code === 'string' && ['BAD_REQUEST','UNAUTHORIZED','FORBIDDEN','NOT_FOUND','TIMEOUT','CONFLICT','INTERNAL_SERVER_ERROR'].includes(code);
Try / catch
try { await api.getSlots(q); }
catch (e) {
if (isTrpcCode(e.code)) {
switch (e.code) {
case 'UNAUTHORIZED': redirectToLogin(); break;
case 'NOT_FOUND': showNotFound(); break;
default: throw e;
}
} else throw e;
} Prevention
- Keep TRPC_ERROR_MAP in sync with the tRPC codes your shared procedures can throw.
- On the client, switch on error.code for UX rather than parsing messages.
- Add a regression test whenever a new tRPC code is introduced upstream.
When it happens
Trigger: getAvailableSlots throws a tRPC-style error message such as 'BAD_REQUEST', 'UNAUTHORIZED', 'FORBIDDEN', 'NOT_FOUND', 'INTERNAL_SERVER_ERROR', etc. — any key of TRPC_ERROR_CODE — which the controller then lifts into a TRPCError for the global trpc-exception filter to render.
Common situations: Reusing core booking/slot tRPC procedures from the API v2 controller; the shared procedure throws a typed tRPC error and the Nest wrapper must translate it; version drift where a new tRPC code is thrown but TRPC_ERROR_MAP has not been updated.
Related errors
- Invalid time range given - check the 'startTime' and 'endTim
- Invalid slot format. Must be either 'range' or 'time'
- Event Type not found
- CustomThrottlerGuard - Too many requests. Please try again l
- CustomThrottlerGuard - Invalid API Key
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/5cf80b7157dfc007.
Report an issue: GitHub.