{"record":{"id":"9ee0b9628787a0f6","repo":"immich-app/immich","slug":"invalid-user-9ee0b9","errorCode":null,"errorMessage":"Invalid user","messagePattern":"Invalid user","errorType":"http","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/partner.service.ts","lineNumber":22,"sourceCode":"import { PartnerCreateDto, PartnerResponseDto, PartnerSearchDto, PartnerUpdateDto } from 'src/dtos/partner.dto';\nimport { mapUser } from 'src/dtos/user.dto';\nimport { Permission } from 'src/enum';\nimport { PartnerDirection, PartnerIds } from 'src/repositories/partner.repository';\nimport { BaseService } from 'src/services/base.service';\n\n@Injectable()\nexport class PartnerService extends BaseService {\n  async create(auth: AuthDto, { sharedWithId }: PartnerCreateDto): Promise<PartnerResponseDto> {\n    const partnerId: PartnerIds = { sharedById: auth.user.id, sharedWithId };\n    const exists = await this.partnerRepository.get(partnerId);\n    if (exists) {\n      throw new BadRequestException(`Partner already exists`);\n    }\n\n    const user = await this.userRepository.get(sharedWithId, {});\n    if (!user) {\n      this.logger.debug('Partner creation failed: user not found');\n      throw new BadRequestException('Invalid user');\n    }\n\n    const partner = await this.partnerRepository.create(partnerId);\n    return this.mapPartner(partner, PartnerDirection.SharedBy);\n  }\n\n  async remove(auth: AuthDto, sharedWithId: string): Promise<void> {\n    const partnerId: PartnerIds = { sharedById: auth.user.id, sharedWithId };\n    const partner = await this.partnerRepository.get(partnerId);\n    if (!partner) {\n      throw new BadRequestException('Partner not found');\n    }\n\n    await this.partnerRepository.remove(partnerId);\n  }\n\n  async search(auth: AuthDto, { direction }: PartnerSearchDto): Promise<PartnerResponseDto[]> {\n    const partners = await this.partnerRepository.getAll(auth.user.id);","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/partner.service.ts#L4-L40","documentation":"Thrown by PartnerService.create when userRepository.get(sharedWithId, {}) returns null after the exists-check passed. Means the requested sharedWithId does not reference a real user. BadRequestException -> HTTP 400. Logged at debug level as 'Partner creation failed: user not found'.","triggerScenarios":"POST /partner with a sharedWithId that is not a registered user, has been hard-deleted, or is a malformed UUID.","commonSituations":"Client passes the wrong user id (e.g. an album id or a device id); the target user was deleted between the UI loading a suggestion list and the create call; a stale cache of user ids.","solutions":["Verify sharedWithId is a valid user id by calling GET /users (or the admin user list) before submitting.","Refresh the user-picker data source if it may be stale.","Handle 400 'Invalid user' in the UI by clearing the selection and re-fetching the user list."],"exampleFix":"// before\nconst user = await this.userRepository.get(sharedWithId, {});\nif (!user) {\n  this.logger.debug('Partner creation failed: user not found');\n  throw new BadRequestException('Invalid user');\n}\n\n// after (use 404 so the semantics match the resource)\nconst user = await this.userRepository.get(sharedWithId, {});\nif (!user) {\n  throw new NotFoundException(`User ${sharedWithId} not found`);\n}","handlingStrategy":"validation","validationCode":"// Confirm the target user exists before submitting the create.\nconst users = await userService.getAll(auth, {}); // or GET /users\nif (!users.find((u) => u.id === sharedWithId)) {\n  throw new Error('Refusing to create partner: target user does not exist');\n}","typeGuard":"const isValidUserId = (id: string): boolean =>\n  /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(id);","tryCatchPattern":"try {\n  await partnerService.create(auth, { sharedWithId });\n} catch (e) {\n  if (e instanceof BadRequestException && e.message === 'Invalid user') {\n    // refresh the user list, clear the stale selection\n  }\n  throw e;\n}","preventionTips":["Source sharedWithId only from a freshly fetched user list.","Validate the UUID format client-side before submitting.","Treat 'Invalid user' as a signal to refresh the picker data."],"tags":["partner","user","validation","nestjs","not-found"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}