[PR #16120] Fix DeleteItem cleanup logic to remove conflicting UserData entries #14530

Open
opened 2026-02-07 07:31:16 +03:00 by OVERLORD · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/jellyfin/jellyfin/pull/16120
Author: @MarcoCoreDuo
Created: 1/26/2026
Status: 🔄 Open

Base: release-10.11.zHead: fix-userdata-cleanup


📝 Commits (2)

  • e1c5118 Fix DeleteItem cleanup logic to remove conflicting UserData entries
  • d7d81ae sort by ItemId if no LastPlayedDate exists

📊 Changes

1 file changed (+26 additions, -0 deletions)

View changed files

📝 Jellyfin.Server.Implementations/Item/BaseItemRepository.cs (+26 -0)

📄 Description

Prior to PR #14795, the item deletion logic handled single items correctly. When deleting an item, Jellyfin checked if a placeholder entry existed in the UserData table with matching UserId, CustomDataKey, and PlaceholderId as ItemId. If found, it was deleted to prevent constraint violations when updating the item's UserData itemId to the placeholderId.

However, PR #14795 changed the method to accept multiple item IDs for batch deletion, which introduced a new edge case.

When multiple items share the same (UserId, CustomDataKey) combination (e.g., duplicate episodes), the current code does not check for conflicts among the items being deleted.

Example scenario:

  1. Two videos of the same episode exist with identical UserId and CustomDataKey but different ItemId values in UserData
  2. Both episodes are deleted in the same batch operation
  3. The code checks for placeholder conflicts but doesn't detect that both items have the same (UserId, CustomDataKey) pair
  4. Both item's UserData entries are updated to use the PlaceholderId as ItemId
  5. This violates the unique constraint on (ItemId, UserId, CustomDataKey)

Changes

  • Identifies UserData entries with duplicate (UserId, CustomDataKey) combinations among items being deleted
  • Keeps only the entry with the newest LastPlayedDate

Issues

Fixes #15343
Fixes #15397
Fixes #15658


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/jellyfin/jellyfin/pull/16120 **Author:** [@MarcoCoreDuo](https://github.com/MarcoCoreDuo) **Created:** 1/26/2026 **Status:** 🔄 Open **Base:** `release-10.11.z` ← **Head:** `fix-userdata-cleanup` --- ### 📝 Commits (2) - [`e1c5118`](https://github.com/jellyfin/jellyfin/commit/e1c51180b4a8af797aded476a85f40fce67b9f2b) Fix DeleteItem cleanup logic to remove conflicting UserData entries - [`d7d81ae`](https://github.com/jellyfin/jellyfin/commit/d7d81aead9d539a8f67ce83acc745abd046f4e80) sort by ItemId if no LastPlayedDate exists ### 📊 Changes **1 file changed** (+26 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `Jellyfin.Server.Implementations/Item/BaseItemRepository.cs` (+26 -0) </details> ### 📄 Description Prior to PR #14795, the item deletion logic handled single items correctly. When deleting an item, Jellyfin checked if a placeholder entry existed in the UserData table with matching UserId, CustomDataKey, and PlaceholderId as ItemId. If found, it was deleted to prevent constraint violations when updating the item's UserData itemId to the placeholderId. However, PR #14795 changed the method to accept multiple item IDs for batch deletion, which introduced a new edge case. When multiple items share the same (UserId, CustomDataKey) combination (e.g., duplicate episodes), the current code does not check for conflicts among the items being deleted. Example scenario: 1. Two videos of the same episode exist with identical UserId and CustomDataKey but different ItemId values in UserData 2. Both episodes are deleted in the same batch operation 3. The code checks for placeholder conflicts but doesn't detect that both items have the same (UserId, CustomDataKey) pair 4. Both item's UserData entries are updated to use the PlaceholderId as ItemId 5. This violates the unique constraint on (ItemId, UserId, CustomDataKey) <!-- Ensure your title is short, descriptive, and in the imperative mood (Fix X, Change Y, instead of Fixed X, Changed Y). For a good inspiration of what to write in commit messages and PRs please review https://chris.beams.io/posts/git-commit/ and our documentation. --> **Changes** <!-- Describe your changes here in 1-5 sentences. --> - Identifies UserData entries with duplicate (UserId, CustomDataKey) combinations among items being deleted - Keeps only the entry with the newest LastPlayedDate **Issues** <!-- Tag any issues that this PR solves here. ex. Fixes # --> Fixes #15343 Fixes #15397 Fixes #15658 --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
OVERLORD added the pull-request label 2026-02-07 07:31:16 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/jellyfin#14530