From 069eb40ebfdca4030d0c87d56f4398f6f5d1b55e Mon Sep 17 00:00:00 2001 From: "Joshua M. Boniface" Date: Sun, 21 Jun 2026 22:49:46 -0400 Subject: [PATCH] Fix too many SQL variables in DeleteItem for large batch deletes The FixIncorrectOwnerIdRelationships migration deletes all duplicate items in a single DeleteItemsUnsafeFast -> DeleteItem(ids) call. Inside DeleteItem, the owned-extras lookup used a raw HashSet.Contains, which EF inlines as one SQL variable per id and overflows SQLite's variable limit on large libraries. Use WhereOneOrMany so the id set is bound as a single json_each parameter, like the rest of the method, making bulk deletes work for unlimited library sizes. --- .../Item/ItemPersistenceService.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Jellyfin.Server.Implementations/Item/ItemPersistenceService.cs b/Jellyfin.Server.Implementations/Item/ItemPersistenceService.cs index 7c0cfe7c15..b10f7c527e 100644 --- a/Jellyfin.Server.Implementations/Item/ItemPersistenceService.cs +++ b/Jellyfin.Server.Implementations/Item/ItemPersistenceService.cs @@ -65,8 +65,13 @@ public class ItemPersistenceService : IItemPersistenceService descendantIds.Add(id); } + // Use WhereOneOrMany instead of a raw HashSet.Contains so large id sets are bound as a + // single parameter (json_each) rather than one SQL variable per id, which would otherwise + // overflow SQLite's variable limit when deleting many items at once (e.g. migrations). + var ownerIds = descendantIds.ToArray(); var extraIds = context.BaseItems - .Where(e => e.OwnerId.HasValue && descendantIds.Contains(e.OwnerId.Value)) + .Where(e => e.OwnerId.HasValue) + .WhereOneOrMany(ownerIds, e => e.OwnerId!.Value) .Select(e => e.Id) .ToArray();