{"record":{"id":"a94c6744aa82f3e4","repo":"immich-app/immich","slug":"syncrequesttype-assetfacesv1-is-deprecated-use-sy","errorCode":null,"errorMessage":"SyncRequestType.AssetFacesV1 is deprecated, use SyncRequestType.AssetFacesV2 instead","messagePattern":"SyncRequestType\\.AssetFacesV1 is deprecated, use SyncRequestType\\.AssetFacesV2 instead","errorType":"exception","errorClass":"BadRequestException","httpStatus":400,"severity":"error","filePath":"server/src/services/sync.service.ts","lineNumber":843,"sourceCode":"    }\n  }\n\n  private async syncPeopleV1(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {\n    const deleteType = SyncEntityType.PersonDeleteV1;\n    const deletes = this.syncRepository.person.getDeletes({ ...options, ack: checkpointMap[deleteType] });\n    for await (const { id, ...data } of deletes) {\n      send(response, { type: deleteType, ids: [id], data });\n    }\n\n    const upsertType = SyncEntityType.PersonV1;\n    const upserts = this.syncRepository.person.getUpserts({ ...options, ack: checkpointMap[upsertType] });\n    for await (const { updateId, ...data } of upserts) {\n      send(response, { type: upsertType, ids: [updateId], data });\n    }\n  }\n\n  private syncAssetFacesV1(): Promise<void> {\n    throw new BadRequestException(\n      'SyncRequestType.AssetFacesV1 is deprecated, use SyncRequestType.AssetFacesV2 instead',\n    );\n  }\n\n  private async syncAssetFacesV2(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {\n    const deleteType = SyncEntityType.AssetFaceDeleteV1;\n    const deletes = this.syncRepository.assetFace.getDeletes({ ...options, ack: checkpointMap[deleteType] });\n    for await (const { id, ...data } of deletes) {\n      send(response, { type: deleteType, ids: [id], data });\n    }\n\n    const upsertType = SyncEntityType.AssetFaceV2;\n    const upserts = this.syncRepository.assetFace.getUpserts({ ...options, ack: checkpointMap[upsertType] });\n    for await (const { updateId, ...data } of upserts) {\n      send(response, { type: upsertType, ids: [updateId], data });\n    }\n  }\n","sourceCodeStart":825,"sourceCodeEnd":861,"githubUrl":"https://github.com/immich-app/immich/blob/199723261c6ffa897fec8ccdaea6359e39c37cc3/server/src/services/sync.service.ts#L825-L861","documentation":"Thrown (as BadRequestException) by SyncService.syncAssetFacesV1, a stub that always rejects. AssetFacesV1 was superseded by AssetFacesV2 and the old stream is disabled.","triggerScenarios":"GET /sync/stream whose SyncRequestType array includes SyncRequestType.AssetFacesV1.","commonSituations":"Client built before the V2 face sync; older desktop app on a newer server.","solutions":["Replace SyncRequestType.AssetFacesV1 with SyncRequestType.AssetFacesV2.","Upgrade the client to the matched server release.","Regenerate SDK and remove V1 enum usage."],"exampleFix":"// before\ntypes: [SyncRequestType.AssetFacesV1]\n// after\ntypes: [SyncRequestType.AssetFacesV2]","handlingStrategy":"validation","validationCode":"const types = clientTypes.filter(t => t !== SyncRequestType.AssetFacesV1);\ntypes.push(SyncRequestType.AssetFacesV2);\nawait syncApi.stream({ types });","typeGuard":"function requestsAssetFacesV1(types: SyncRequestType[]): boolean {\n  return types.includes(SyncRequestType.AssetFacesV1);\n}","tryCatchPattern":null,"preventionTips":["Switch face sync to AssetFacesV2 before server upgrade.","Regenerate the face-sync SDK types from current openapi.","Confirm the face detection pipeline ran before expecting V2 data."],"tags":["sync","deprecation","version-skew","bad-request","faces"],"backgroundTag":null,"analyzedSha":"199723261c6ffa897fec8ccdaea6359e39c37cc3","analyzedAt":"2026-08-12T04:54:27.085Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}