immich-app/immich · error · BadRequestException
SyncRequestType.AssetsV1 is deprecated, use SyncRequestType.
Error message
SyncRequestType.AssetsV1 is deprecated, use SyncRequestType.AssetsV2 instead
What it means
Thrown (as BadRequestException) by SyncService.syncAssetsV1, which is now a stub: the AssetsV1 sync stream was removed and unconditionally throws. Clients must request SyncRequestType.AssetsV2. This is a hard deprecation, not a graceful fallback.
Source
Thrown at server/src/services/sync.service.ts:278
}
}
private async syncPartnersV1(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
const deleteType = SyncEntityType.PartnerDeleteV1;
const deletes = this.syncRepository.partner.getDeletes({ ...options, ack: checkpointMap[deleteType] });
for await (const { id, ...data } of deletes) {
send(response, { type: deleteType, ids: [id], data });
}
const upsertType = SyncEntityType.PartnerV1;
const upserts = this.syncRepository.partner.getUpserts({ ...options, ack: checkpointMap[upsertType] });
for await (const { updateId, ...data } of upserts) {
send(response, { type: upsertType, ids: [updateId], data });
}
}
private syncAssetsV1(): Promise<void> {
throw new BadRequestException('SyncRequestType.AssetsV1 is deprecated, use SyncRequestType.AssetsV2 instead');
}
private async syncAssetsV2(options: SyncQueryOptions, response: Writable, checkpointMap: CheckpointMap) {
const deleteType = SyncEntityType.AssetDeleteV1;
const deletes = this.syncRepository.asset.getDeletes({ ...options, ack: checkpointMap[deleteType] });
for await (const { id, ...data } of deletes) {
send(response, { type: deleteType, ids: [id], data });
}
const upsertType = SyncEntityType.AssetV2;
const upserts = this.syncRepository.asset.getUpserts({ ...options, ack: checkpointMap[upsertType] });
for await (const { updateId, ...data } of upserts) {
send(response, { type: upsertType, ids: [updateId], data: mapSyncAssetV2(data) });
}
}
private syncPartnerAssetsV1(): Promise<void> {
throw new BadRequestException(View on GitHub (pinned to 199723261c)
Solutions
- Remove SyncRequestType.AssetsV1 from the client's requested types and request AssetsV2 instead.
- Update the Immich client (mobile/web) to a release that emits AssetsV2.
- Regenerate the SDK from the current openapi.json and recompile.
Example fix
// before types: [SyncRequestType.AssetsV1] // after types: [SyncRequestType.AssetsV2]
Defensive patterns
Strategy: validation
Validate before calling
const requested = [SyncRequestType.AssetsV1].filter(t => t !== SyncRequestType.AssetsV1);
requested.push(SyncRequestType.AssetsV2);
await syncApi.stream({ types: requested }); Type guard
function isV1AssetRequest(types: SyncRequestType[]): boolean {
return types.includes(SyncRequestType.AssetsV1);
} Prevention
- Remove all SyncRequestType.*V1 references from client code.
- Gate sync request types behind a generated enum, never hard-coded literals.
- Test sync against the same server version you ship.
When it happens
Trigger: GET /sync/stream with a SyncRequestType including SyncRequestType.AssetsV1 in the request types array.
Common situations: Old mobile/desktop client built against a pre-V2 server; cached client config still lists AssetsV1; integration test fixtures not updated after upgrade.
Related errors
- SyncRequestType.PartnerAssetsV1 is deprecated, use SyncReque
- SyncRequestType.AlbumAssetsV1 is deprecated, use SyncRequest
- SyncRequestType.AssetFacesV1 is deprecated, use SyncRequestT
- 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/1c7635bfac071352.
Report an issue: GitHub.