{"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":896,"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      await 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      await 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  // TODO(v5) drop when AssetFacesV2 is removed\n  private async syncAssetFacesV2(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {\n    const deleteType = SyncEntityType.AssetFaceDeleteV1;\n    const deletes = this.syncRepository.assetFace.getDeletesV2({ ...options, ack: checkpointMap[deleteType] });\n    for await (const { id, ...data } of deletes) {\n      await send(response, { type: deleteType, ids: [id], data });\n    }\n\n    const upsertType = SyncEntityType.AssetFaceV2;\n    const upserts = this.syncRepository.assetFace.getUpsertsV2({ ...options, ack: checkpointMap[upsertType] });\n    for await (const { updateId, ...data } of upserts) {\n      await send(response, { type: upsertType, ids: [updateId], data });\n    }\n  }","sourceCodeStart":878,"sourceCodeEnd":914,"githubUrl":"https://github.com/immich-app/immich/blob/f48d4b332127ad365ba256108799ca8f571d2dd5/server/src/services/sync.service.ts#L878-L914","documentation":"Generic deprecation guard: the AssetFacesV1 sync handler is now a stub that throws for any client still requesting SyncRequestType.AssetFacesV1, since face data moved to the AssetFacesV2 protocol. It always throws when the legacy type is selected, telling outdated clients to upgrade their sync request type; the at-fault input is the deprecated SyncRequestType.AssetFacesV1 query parameter.","triggerScenarios":"Client includes SyncRequestType.AssetFacesV1 in its sync request; handlers dispatches to syncAssetFacesV1 which always throws.","commonSituations":"Facial-recognition sync from older apps against a newer server.","solutions":["Update the Immich mobile app to an AssetFacesV2-capable version","Replace AssetFacesV1 with SyncRequestType.AssetFacesV2 in the sync request"],"exampleFix":"// before\nrequests: [{ type: SyncRequestType.AssetFacesV1 }]\n// after\nrequests: [{ type: SyncRequestType.AssetFacesV2 }]","handlingStrategy":"validation","validationCode":"if (requests.some(r => r.type === SyncRequestType.AssetFacesV1)) throw new Error('Use AssetFacesV2');","typeGuard":"null","tryCatchPattern":"try {\n  await syncStream(requests);\n} catch (e) {\n  if (e.status === 400 && e.message.includes('AssetFacesV1')) {\n    requests = requests.map(r => r.type === 'AssetFacesV1' ? { ...r, type: 'AssetFacesV2' } : r);\n  }\n}","preventionTips":["Use AssetFacesV2 for face sync","Keep the mobile app current","Handle face deletes via AssetFaceDeleteV1 checkpoints"],"tags":["sync","deprecated","api-version","faces"],"backgroundTag":"deprecated-api-usage","analyzedSha":"f48d4b332127ad365ba256108799ca8f571d2dd5","analyzedAt":"2026-09-15T07:20:19.675Z","contentChangedAt":"2026-09-15T07:20:19.675Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}