calcom/cal.diy · critical · BadRequestException
Failed to update private link
Error message
Failed to update private link
What it means
Fallback BadRequestException thrown by PrivateLinksService.updatePrivateLink when the caught value is NOT an instance of Error. This is the defensive branch for code that throws a non-Error value (string, plain object, null) somewhere in the update pipeline. It masks the original cause behind a generic message, so debugging requires reproducing the throw shape.
Source
Thrown at apps/api/v2/src/platform/event-types-private-links/services/private-links.service.ts:101
if (!updated) throw new NotFoundException("Updated link not found");
const mapped: PrivateLinkData = {
id: updated.link,
eventTypeId,
isExpired: isLinkExpired(updated as any),
bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || "https://cal.com"}/d/${updated.link}`,
expiresAt: updated.expiresAt ?? null,
maxUsageCount: updated.maxUsageCount ?? null,
usageCount: updated.usageCount ?? 0,
};
return this.outputService.transformToOutput(mapped);
} catch (error) {
if (error instanceof Error) {
if (error.message.includes("not found")) {
throw new NotFoundException(error.message);
}
throw new BadRequestException(error.message);
}
throw new BadRequestException("Failed to update private link");
}
}
async deletePrivateLink(eventTypeId: number, linkId: string): Promise<void> {
try {
const { count } = await this.repo.delete(eventTypeId, linkId);
if (count === 0) {
throw new NotFoundException("Deleted link not found");
}
} catch (error) {
if (error instanceof Error) {
if (error.message.includes("not found")) {
throw new NotFoundException(error.message);
}
throw new BadRequestException(error.message);
}
throw new BadRequestException("Failed to delete private link");
}View on GitHub (pinned to 176037d0af)
Solutions
- Search the repo for `throw` statements that throw non-Error values (e.g. `throw "` or `throw {`) and convert them to `throw new Error(...)`.
- Reproduce locally with debug logging in the catch block to print `typeof error` and the value, then trace it to its source.
- If originating from a library, wrap its calls so errors are normalized to Error instances before reaching this service.
- File an issue: a generic 400 here hides the real failure; the service should log the raw caught value before falling back.
Example fix
// before (in some downstream repo)
if (!row) throw 'link missing';
// after
if (!row) throw new Error('link missing'); Defensive patterns
Strategy: try-catch
Try / catch
// Client cannot prevent a non-Error throw on the server; catch and escalate
try {
await api.patch(url, payload);
} catch (e) {
if (e.response?.status === 400 && e.response?.data?.message === 'Failed to update private link') {
// opaque server-side defect; retry once, then surface to ops
} else throw e;
} Prevention
- Report this to the server team — a generic 400 here is a defect, not a client error.
- Pin your dependency versions so transitive upgrades do not introduce non-Error throws.
- Add an integration test that asserts the service rejects bad input with a specific message, not the fallback.
When it happens
Trigger: A downstream dependency does `throw 'string error'` or `throw { code: 123 }` instead of `throw new Error(...)`; a Prisma or library bug throws a non-Error; an assertion library configured to throw raw values; a Promise rejection with a non-Error reason.
Common situations: Third-party middleware or a custom repository method that rejects with a string; an older Node.js library that throws primitives; a bug in outputService.transformToOutput that throws a plain object. This is almost always a defect in the service's own dependency tree, not a client error.
Related errors
- Failed to delete private link
- Could not find public event.
- ApiKeysService -Cannot set both apiKeyDaysValid and apiKeyNe
- teamId is required for team events, please provide a valid t
- username is required for non-team events, please provide a v
AI-assisted analysis of calcom/cal.diy@176037d0af (2026-08-12).
Data as JSON: /api/errors/79fb398c7e3126ea.
Report an issue: GitHub.