{"record":{"id":"008cc01a56bbbfd5","repo":"calcom/cal.diy","slug":"failed-to-create-private-link","errorCode":null,"errorMessage":"Failed to create private link","messagePattern":"Failed to create private link","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/event-types-private-links/services/private-links.service.ts","lineNumber":46,"sourceCode":"        link: generateHashedLink(userId),\n        expiresAt: transformedInput.expiresAt ?? null,\n        maxUsageCount: transformedInput.maxUsageCount ?? null,\n      });\n      const mapped: PrivateLinkData = {\n        id: created.link,\n        eventTypeId,\n        isExpired: isLinkExpired(created as any),\n        bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || \"https://cal.com\"}/d/${created.link}`,\n        expiresAt: created.expiresAt ?? null,\n        maxUsageCount: (created as any).maxUsageCount ?? null,\n        usageCount: (created as any).usageCount ?? 0,\n      };\n      return this.outputService.transformToOutput(mapped);\n    } catch (error) {\n      if (error instanceof Error) {\n        throw new BadRequestException(error.message);\n      }\n      throw new BadRequestException(\"Failed to create private link\");\n    }\n  }\n\n  async getPrivateLinks(eventTypeId: number): Promise<PrivateLinkOutput[]> {\n    try {\n      const links = await this.repo.listByEventTypeId(eventTypeId);\n      const mapped: PrivateLinkData[] = links.map((l) => ({\n        id: l.link,\n        eventTypeId,\n        isExpired: isLinkExpired(l as any),\n        bookingUrl: `${process.env.NEXT_PUBLIC_WEBAPP_URL || \"https://cal.com\"}/d/${l.link}`,\n        expiresAt: l.expiresAt ?? null,\n        maxUsageCount: l.maxUsageCount ?? null,\n        usageCount: l.usageCount ?? 0,\n      }));\n      return this.outputService.transformArrayToOutput(mapped);\n    } catch (error) {\n      if (error instanceof Error) {","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/event-types-private-links/services/private-links.service.ts#L28-L64","documentation":"The fallback in PrivateLinksService.createPrivateLink's catch: if the thrown value is NOT an instance of Error (e.g. a Prisma error object with a different prototype, a non-Error thrown by a dependency, or a plain object), BadRequestException('Failed to create private link') is raised as a generic message. This is the lossy path: the original cause is dropped from the response.","triggerScenarios":"A Prisma PrismaClientKnownRequestError that on some code paths isn't an Error instance; a dependency throwing a non-Error value; a serialization failure inside the mapping block (e.g. created.link undefined -> bookingUrl malformed); any non-Error rejection from generateHashedLink or repo.create.","commonSituations":"DB outage mid-create; unique-constraint violation surfaced as a non-Error; a refactor that changed what repo.create throws; integration tests throwing plain objects.","solutions":["Inspect the API server logs: the generic response hides the cause but the logger/stack should still record it.","If reproducible, add a temporary console.error of the caught value to see its shape, then handle it explicitly.","Verify the input passes transformCreateInput before posting."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await privateLinksService.createPrivateLink(eventTypeId, userId, input);\n} catch (e) {\n  if (e instanceof BadRequestException && e.message === 'Failed to create private link') {\n    // generic fallback; inspect server logs for the non-Error cause\n  } else throw e;\n}","preventionTips":["Pre-validate input so the only remaining failures are DB-side and rare.","Log the raw caught value server-side so non-Error rejections are diagnosable.","Treat the generic message as a server fault and retry once after checking logs."],"tags":["private-links","catch-all","api-v2"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}