{"record":{"id":"8385ea773771ca88","repo":"calcom/cal.diy","slug":"unable-to-create-user-credential-for-giphy","errorCode":null,"errorMessage":"Unable to create user credential for giphy","messagePattern":"Unable to create user credential for giphy","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"info","filePath":"packages/app-store/giphy/api/add.ts","lineNumber":45,"sourceCode":"    const alreadyInstalled = await prisma.credential.findFirst({\n      where: {\n        type: appType,\n        ...credentialOwner,\n      },\n    });\n    if (alreadyInstalled) {\n      throw new Error(\"Already installed\");\n    }\n    const installation = await prisma.credential.create({\n      data: {\n        type: appType,\n        key: {},\n        ...credentialOwner,\n        appId: \"giphy\",\n      },\n    });\n    if (!installation) {\n      throw new Error(\"Unable to create user credential for giphy\");\n    }\n  } catch (error: unknown) {\n    const httpError = getServerErrorFromUnknown(error);\n    return res.status(httpError.statusCode).json({ message: httpError.message });\n  }\n\n  return res.status(200).json({ url: getInstalledAppPath({ variant: \"other\", slug: \"giphy\" }) });\n}\n","sourceCodeStart":27,"sourceCodeEnd":54,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/packages/app-store/giphy/api/add.ts#L27-L54","documentation":"Thrown if `prisma.credential.create` returns a falsy value. Per Prisma's contract, `create` either returns the created row or throws (e.g. P2002 unique-constraint → `getServerErrorFromPrismaError` maps to 400); it never returns null. This branch is therefore effectively unreachable defensive code, and were it to fire it would surface as HTTP 500 because it is a plain `Error`. Real create failures are reported as Prisma errors (400), not via this message.","triggerScenarios":"Only reachable if `prisma.credential.create` returned `null`/`undefined` — which contradicts Prisma's documented behavior. In practice never hit; the only realistic way to trigger it is a test that stubs/mocks `create` to return undefined.","commonSituations":"A unit test mocks `prisma.credential.create` to resolve to `undefined`; otherwise not observed in production. Any genuine DB failure surfaces earlier as a thrown Prisma error caught at line 47.","solutions":["If you encounter this in logs, suspect mocking/stubbing of `prisma.credential.create`; the real failure path is the Prisma exception, not this branch.","Remove the dead `if (!installation)` check (Prisma guarantees a returned record) to avoid misleading 500 semantics, or convert it to an explicit `HttpError({ statusCode: 500 })` assertion if kept.","For genuine install failures, inspect the Prisma error code in the surrounding `catch` (P2002 = duplicate, P2003 = FK, etc.)."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// The branch is unreachable; real failures surface as Prisma errors in the surrounding catch.\n// Handle those explicitly instead of expecting this message.\ntry {\n  await prisma.credential.create({\n    data: { type: \"giphy_other\", key: {}, ...credentialOwner, appId: \"giphy\" },\n  });\n} catch (error) {\n  if (error instanceof Prisma.PrismaClientKnownRequestError && error.code === \"P2002\") {\n    // duplicate install — handle as 'already installed'\n  } else {\n    throw error; // getServerErrorFromUnknown maps P2003/P2025/etc. appropriately\n  }\n}","preventionTips":["Do not stub `prisma.credential.create` to return undefined in tests — that is the only way to reach this branch.","Rely on Prisma's throw-on-failure contract; do not add null-checks that imply create can silently fail.","If this message appears in production logs, suspect a mocked client or a non-Prisma datasource impersonating the credential model."],"tags":["app-store","giphy","prisma","dead-code","unreachable"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}