{"record":{"id":"355a9a6d9045ed83","repo":"calcom/cal.diy","slug":"user-with-id-userid-is-not-part-of-this-oauth-c","errorCode":null,"errorMessage":"User with ID ${userId} is not part of this OAuth client.","messagePattern":"User with ID (.+?) is not part of this OAuth client\\.","errorType":"exception","errorClass":"NotFoundException","httpStatus":404,"severity":"error","filePath":"apps/api/v2/src/modules/oauth-clients/controllers/oauth-client-users/oauth-client-users.controller.ts","lineNumber":213,"sourceCode":"\n    const { accessToken, refreshToken, accessTokenExpiresAt, refreshTokenExpiresAt } =\n      await this.tokensRepository.forceRefreshOAuthTokens(oAuthClientId, id);\n\n    return {\n      status: SUCCESS_STATUS,\n      data: {\n        accessToken,\n        refreshToken,\n        accessTokenExpiresAt: accessTokenExpiresAt.valueOf(),\n        refreshTokenExpiresAt: refreshTokenExpiresAt.valueOf(),\n      },\n    };\n  }\n\n  private async validateManagedUserOwnership(clientId: string, userId: number): Promise<User> {\n    const user = await this.userRepository.findByIdWithinPlatformScope(userId, clientId);\n    if (!user) {\n      throw new NotFoundException(`User with ID ${userId} is not part of this OAuth client.`);\n    }\n\n    return user;\n  }\n}\n","sourceCodeStart":195,"sourceCodeEnd":219,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/modules/oauth-clients/controllers/oauth-client-users/oauth-client-users.controller.ts#L195-L219","documentation":"Thrown by OAuthClientUsersController.validateManagedUserOwnership when userRepository.findByIdWithinPlatformScope(userId, clientId) returns falsy. The helper restricts the lookup to the given OAuth client's platform scope, so it fails both when the user does not exist and when the user exists but was not created under that OAuth client. Raised as NotFoundException (HTTP 404) per the message.","triggerScenarios":"An operation on a managed user (e.g. token refresh, update, delete) passes a userId that is not a managed user of the supplied clientId. The scoped repository query returns nothing and the guard throws before proceeding.","commonSituations":"Cross-client access: using a userId from OAuth client A against client B; userId from a stale list after the managed user was removed; clientId/userId parameter swap in the caller; the managed user was migrated or reassigned.","solutions":["List managed users for the clientId (GET endpoint) and use an id that is actually scoped to that client.","Confirm clientId and userId come from the same OAuth client context (do not mix ids across clients).","If the managed user was deleted, inform the caller and re-create or pick an existing one."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const user = await userRepository.findByIdWithinPlatformScope(userId, clientId);\nif (!user) {\n  throw new NotFoundException(`User with ID ${userId} is not part of this OAuth client.`);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always scope managed-user queries by both userId and clientId.","Keep clientId and userId sourced from the same OAuth client context.","List managed users before acting on an id from a cached list."],"tags":["oauth-clients","managed-users","ownership","not-found","authorization","nestjs"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}