{"record":{"id":"741fd4a00de08749","repo":"calcom/cal.diy","slug":"user-with-id-newuserid-is-not-a-valid-round-rob","errorCode":null,"errorMessage":"User with id=${newUserId} is not a valid Round Robin host - the user to which you reassign this booking must be one of the booking hosts. Fetch the booking using the GET /v2/bookings/{uid} endpoint and select id of one of the hosts.","messagePattern":"User with id=(.+?) is not a valid Round Robin host - the user to which you reassign this booking must be one of the booking hosts\\. Fetch the booking using the GET /v2/bookings/(.+?) endpoint and select id of one of the hosts\\.","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts","lineNumber":1113,"sourceCode":"        reassignedById: reassignedByUser.id,\n        emailsEnabled,\n        platformClientParams,\n        actionSource: \"API_V2\",\n        reassignedByUuid: reassignedByUser.uuid,\n      });\n\n      const reassigned = await this.bookingsRepository.getByUidWithUser(bookingUid);\n      if (!reassigned) {\n        throw new NotFoundException(\n          `Reassigned booking with uid=${bookingUid} was not found in the database`\n        );\n      }\n\n      return this.outputService.getOutputReassignedBooking(reassigned);\n    } catch (error) {\n      if (error instanceof Error) {\n        if (error.message === \"invalid_round_robin_host\") {\n          throw new BadRequestException(\n            `User with id=${newUserId} is not a valid Round Robin host - the user to which you reassign this booking must be one of the booking hosts. Fetch the booking using the GET /v2/bookings/{uid} endpoint and select id of one of the hosts.`\n          );\n        }\n      }\n      throw error;\n    }\n  }\n\n  async confirmBooking(bookingUid: string, requestUser: ApiAuthGuardUser) {\n    const booking = await this.bookingsRepository.getByUid(bookingUid);\n    if (!booking) {\n      throw new NotFoundException(`Booking with uid=${bookingUid} was not found in the database`);\n    }\n\n    const platformClientParams = booking.eventTypeId\n      ? await this.platformBookingsService.getOAuthClientParams(booking.eventTypeId)\n      : undefined;\n","sourceCodeStart":1095,"sourceCodeEnd":1131,"githubUrl":"https://github.com/calcom/cal.diy/blob/176037d0afbe572f870a3c702985e7cd83fe6c0c/apps/api/v2/src/platform/bookings/2024-08-13/services/bookings.service.ts#L1095-L1131","documentation":"Thrown in reassignBookingToUser's catch block when roundRobinManualReassignment rejects with the literal message \"invalid_round_robin_host\". NestJS BadRequestException (HTTP 400). It means the newUserId is not one of the designated round-robin hosts for the booking - manual reassignment may only target an existing host. The message itself tells the caller to GET the booking and pick a host id.","triggerScenarios":"POST reassign-to-user with a newUserId who is a valid user but is NOT in the booking's host set (e.g., a teammate who was never added to the event type, or a user removed from the round-robin pool).","commonSituations":"Assuming any org member can receive the booking; using the booking owner id when they are no longer an active host; host membership changed between fetching the user and the call.","solutions":["GET /v2/bookings/{uid} and choose newUserId strictly from the returned hosts array.","If you need a non-host user, first add them as a host on the event type, then reassign.","Re-fetch hosts immediately before the call to avoid stale host lists.","Validate the chosen id against the live host set client-side."],"exampleFix":"// before\nawait apiClient.post(`/v2/bookings/${uid}/reassign-to-user`, { userId: someUserId });\n\n// after\nconst booking = await apiClient.get(`/v2/bookings/${uid}`).then(r => r.data);\nconst validHost = (booking.hosts ?? []).find(h => h.id === someUserId);\nif (!validHost) throw new Error(`${someUserId} is not a round-robin host of booking ${uid}`);\nawait apiClient.post(`/v2/bookings/${uid}/reassign-to-user`, { userId: validHost.id });","handlingStrategy":"validation","validationCode":"// Ensure the target user is one of the booking's round-robin hosts\nconst booking = await apiClient.get(`/v2/bookings/${uid}`).then(r => r.data);\nconst validHost = (booking.hosts ?? []).find(h => h.id === newUserId);\nif (!validHost) {\n  throw new Error(`User ${newUserId} is not a round-robin host of booking ${uid}; pick from [${(booking.hosts ?? []).map(h => h.id).join(', ')}]`);\n}","typeGuard":"function isRoundRobinHost(userId: number, booking: { hosts?: Array<{ id: number }> }): boolean {\n  return (booking.hosts ?? []).some(h => h.id === userId);\n}","tryCatchPattern":"try {\n  await apiClient.post(`/v2/bookings/${uid}/reassign-to-user`, { userId: newUserId });\n} catch (err) {\n  if (err.response?.status === 400 && /not a valid Round Robin host/i.test(err.response?.data?.message ?? '')) {\n    const hosts = await apiClient.get(`/v2/bookings/${uid}`).then(r => (r.data.hosts ?? []).map(h => h.id));\n    throw new InvalidHostError(`Pick one of: ${hosts.join(', ')}`);\n  }\n  throw err;\n}","preventionTips":["Always derive newUserId from GET /v2/bookings/{uid}.hosts.","If a non-host must receive the booking, add them as an event-type host first.","Re-fetch the host list right before the call to avoid staleness."],"tags":["round-robin","validation","booking","api-v2","reassign","bad-request"],"backgroundTag":null,"analyzedSha":"176037d0afbe572f870a3c702985e7cd83fe6c0c","analyzedAt":"2026-08-12T19:12:41.464Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}