aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShadowghost <Ghost_of_Stone@web.de>2026-02-15 19:49:30 +0100
committerShadowghost <Ghost_of_Stone@web.de>2026-02-15 19:49:30 +0100
commit837c7d4ed3edc8c4fcf2640bd6341bb792888244 (patch)
tree93106a7ed99bf2c99bdc346cd54c4a75a0918b8a
parent4ce03ffa21c8bc8a93ac004a6c691d85f78d1503 (diff)
Try fixing orphan versions again
-rw-r--r--Jellyfin.Server/Migrations/Routines/MigrateLinkedChildren.cs44
1 files changed, 9 insertions, 35 deletions
diff --git a/Jellyfin.Server/Migrations/Routines/MigrateLinkedChildren.cs b/Jellyfin.Server/Migrations/Routines/MigrateLinkedChildren.cs
index d43cd785cd..237b01c6f0 100644
--- a/Jellyfin.Server/Migrations/Routines/MigrateLinkedChildren.cs
+++ b/Jellyfin.Server/Migrations/Routines/MigrateLinkedChildren.cs
@@ -278,51 +278,25 @@ internal class MigrateLinkedChildren : IDatabaseMigrationRoutine
{
_logger.LogInformation("Starting cleanup of orphaned alternate version BaseItems...");
- // Check 1: Find BaseItems that have PrimaryVersionId set (they were alternate versions)
- // but no LinkedChild entry references them — meaning they're orphaned.
- // This happens when a version file is renamed: the old BaseItem remains
- // in the DB with a stale PrimaryVersionId but nothing links to it anymore.
+ // Find BaseItems that have OwnerId set (they belonged to another item) and are not extras,
+ // but no LinkedChild entry references them — meaning they're orphaned alternate versions.
+ // This happens when a version file is renamed: the old BaseItem remains in the DB
+ // with a stale OwnerId but nothing links to it anymore.
var orphanedVersionIds = context.BaseItems
- .Where(b => b.PrimaryVersionId != null && b.PrimaryVersionId != string.Empty)
+ .Where(b => b.OwnerId.HasValue && b.ExtraType == null)
.Where(b => !context.LinkedChildren.Any(lc => lc.ChildId.Equals(b.Id)))
.Select(b => b.Id)
.ToList();
- _logger.LogInformation("Found {Count} orphaned alternate versions with stale PrimaryVersionId.", orphanedVersionIds.Count);
-
- // Check 2: Find generic Video items that share a parent folder with a Movie/Episode
- // but are not linked as alternate versions. These are orphaned entries from renamed
- // alternate version files where PrimaryVersionId was already cleared by the old server.
- var specificVideoTypes = new[]
- {
- "MediaBrowser.Controller.Entities.Movies.Movie",
- "MediaBrowser.Controller.Entities.TV.Episode"
- };
-
- var orphanedVideoIds = context.BaseItems
- .Where(b => b.Type == "MediaBrowser.Controller.Entities.Video")
- .Where(b => b.ExtraType == null && !b.OwnerId.HasValue)
- .Where(b => !context.LinkedChildren.Any(lc => lc.ChildId.Equals(b.Id)))
- .Where(b => b.ParentId.HasValue
- && context.BaseItems.Any(sibling =>
- sibling.ParentId.Equals(b.ParentId)
- && specificVideoTypes.Contains(sibling.Type)))
- .Select(b => b.Id)
- .ToList();
-
- _logger.LogInformation("Found {Count} orphaned generic Video items in movie/episode folders.", orphanedVideoIds.Count);
-
- var allOrphanedIds = orphanedVersionIds.Union(orphanedVideoIds).ToList();
-
- if (allOrphanedIds.Count == 0)
+ if (orphanedVersionIds.Count == 0)
{
_logger.LogInformation("No orphaned alternate version BaseItems found.");
return;
}
- _logger.LogInformation("Removing {Count} total orphaned alternate version BaseItems.", allOrphanedIds.Count);
+ _logger.LogInformation("Found {Count} orphaned alternate version BaseItems to remove.", orphanedVersionIds.Count);
- foreach (var id in allOrphanedIds)
+ foreach (var id in orphanedVersionIds)
{
var item = _libraryManager.GetItemById(id);
if (item is not null)
@@ -331,7 +305,7 @@ internal class MigrateLinkedChildren : IDatabaseMigrationRoutine
}
}
- _logger.LogInformation("Removed {Count} orphaned alternate version BaseItems.", allOrphanedIds.Count);
+ _logger.LogInformation("Removed {Count} orphaned alternate version BaseItems.", orphanedVersionIds.Count);
}
private void CleanupOrphanedLinkedChildren(JellyfinDbContext context)