immich-app/immich · error · BadRequestException
SyncRequestType.AssetFacesV1 is deprecated, use SyncRequestT
Error message
SyncRequestType.AssetFacesV1 is deprecated, use SyncRequestType.AssetFacesV2 instead
What it means
Thrown (as BadRequestException) by SyncService.syncAssetFacesV1, a stub that always rejects. AssetFacesV1 was superseded by AssetFacesV2 and the old stream is disabled.
Source
Thrown at server/src/services/sync.service.ts:843
}
}
private async syncPeopleV1(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
const deleteType = SyncEntityType.PersonDeleteV1;
const deletes = this.syncRepository.person.getDeletes({ ...options, ack: checkpointMap[deleteType] });
for await (const { id, ...data } of deletes) {
send(response, { type: deleteType, ids: [id], data });
}
const upsertType = SyncEntityType.PersonV1;
const upserts = this.syncRepository.person.getUpserts({ ...options, ack: checkpointMap[upsertType] });
for await (const { updateId, ...data } of upserts) {
send(response, { type: upsertType, ids: [updateId], data });
}
}
private syncAssetFacesV1(): Promise<void> {
throw new BadRequestException(
'SyncRequestType.AssetFacesV1 is deprecated, use SyncRequestType.AssetFacesV2 instead',
);
}
private async syncAssetFacesV2(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
const deleteType = SyncEntityType.AssetFaceDeleteV1;
const deletes = this.syncRepository.assetFace.getDeletes({ ...options, ack: checkpointMap[deleteType] });
for await (const { id, ...data } of deletes) {
send(response, { type: deleteType, ids: [id], data });
}
const upsertType = SyncEntityType.AssetFaceV2;
const upserts = this.syncRepository.assetFace.getUpserts({ ...options, ack: checkpointMap[upsertType] });
for await (const { updateId, ...data } of upserts) {
send(response, { type: upsertType, ids: [updateId], data });
}
}
View on GitHub (pinned to 199723261c)
Solutions
- Replace SyncRequestType.AssetFacesV1 with SyncRequestType.AssetFacesV2.
- Upgrade the client to the matched server release.
- Regenerate SDK and remove V1 enum usage.
Example fix
// before types: [SyncRequestType.AssetFacesV1] // after types: [SyncRequestType.AssetFacesV2]
Defensive patterns
Strategy: validation
Validate before calling
const types = clientTypes.filter(t => t !== SyncRequestType.AssetFacesV1);
types.push(SyncRequestType.AssetFacesV2);
await syncApi.stream({ types }); Type guard
function requestsAssetFacesV1(types: SyncRequestType[]): boolean {
return types.includes(SyncRequestType.AssetFacesV1);
} Prevention
- 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.
When it happens
Trigger: GET /sync/stream whose SyncRequestType array includes SyncRequestType.AssetFacesV1.
Common situations: Client built before the V2 face sync; older desktop app on a newer server.
Related errors
- SyncRequestType.AssetsV1 is deprecated, use SyncRequestType.
- SyncRequestType.PartnerAssetsV1 is deprecated, use SyncReque
- SyncRequestType.AlbumAssetsV1 is deprecated, use SyncRequest
- Invalid ack type: ${type}
- This endpoint can only be used with a session token
AI-assisted analysis of immich-app/immich@199723261c (2026-08-12).
Data as JSON: /api/errors/a94c6744aa82f3e4.
Report an issue: GitHub.