[PR #14978] [MERGED] Prevent PlaylistsFolder deletion during library removal #14209

Closed
opened 2026-02-07 07:26:13 +03:00 by OVERLORD · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/jellyfin/jellyfin/pull/14978
Author: @theguymadmax
Created: 10/11/2025
Status: Merged
Merged: 10/12/2025
Merged by: @joshuaboniface

Base: masterHead: fix-playlistfolder


📝 Commits (1)

  • 49c3443 Prevent PlaylistsFolder deletion during library removal

📊 Changes

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

View changed files

📝 MediaBrowser.Controller/Entities/Folder.cs (+6 -0)

📄 Description

After deleting any library, the PlaylistsFolder was also removed from the database, which would cause an exception if the user then tried to add an item to a playlist.

Changes

Added CanDelete() check before deleting items in ValidateChildrenInternal2 method

Issues

Log Error
[2025-10-10 04:16:17.781 +00:00] [WRN] [99] MediaBrowser.Controller.Entities.BaseItem: Library folder "/config/data/playlists" is inaccessible or empty, skipping
[2025-10-10 04:16:17.784 +00:00] [INF] [99] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "Folder", Name: "Movies 1", Path: "/MediaI/MediaI/Test Libraries/Movies/Movies 1", Id: bf40c806-c9af-07b6-1530-b34546e524de
[2025-10-10 04:16:18.373 +00:00] [INF] [99] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "PlaylistsFolder", Name: "Playlists", Path: "/config/data/playlists", Id: 1071671e-7bff-a053-2e93-0debee501d2e
[2025-10-10 04:16:19.182 +00:00] [INF] [67] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "CollectionFolder", Name: "Movies2", Path: "/config/root/default/Movies2", Id: 7f09ac8d-4f2f-9f30-6712-c0d21acd9863
[2025-10-10 04:16:19.546 +00:00] [INF] [99] Emby.Server.Implementations.Library.LibraryManager: Validating media library
[2025-10-10 04:16:48.840 +00:00] [WRN] [31] MediaBrowser.Controller.Entities.BaseItem: Library folder "/config/data/playlists" is inaccessible or empty, skipping
[2025-10-10 04:17:05.029 +00:00] [WRN] [96] MediaBrowser.Controller.Entities.BaseItem: Library folder "/config/data/playlists" is inaccessible or empty, skipping
[2025-10-10 04:17:43.201 +00:00] [INF] [38] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.3" closed
[2025-10-10 04:22:15.895 +00:00] [INF] [37] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.3" request
[2025-10-10 04:22:43.914 +00:00] [INF] [70] Emby.Server.Implementations.ScheduledTasks.TaskManager: "Scan Media Library" Completed after 6 minute(s) and 24 seconds
[2025-10-10 04:22:44.902 +00:00] [INF] [43] Emby.Server.Implementations.IO.LibraryMonitor: Watching directory "/MediaD/MediaD/Movies"
[2025-10-10 04:55:24.407 +00:00] [INF] [94] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.3" request
[2025-10-10 04:56:38.788 +00:00] [ERR] [29] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL "POST" "/Playlists".
System.ArgumentException: parentFolder
   at Emby.Server.Implementations.Playlists.PlaylistManager.CreatePlaylist(PlaylistCreationRequest request)
   at Jellyfin.Api.Controllers.PlaylistsController.CreatePlaylist(String name, IReadOnlyList`1 ids, Nullable`1 userId, Nullable`1 mediaType, CreatePlaylistDto createPlaylistRequest)
   at lambda_method360482(Closure, Object)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync()
--- End of stack trace from previous location ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Jellyfin.Api.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager)
   at Jellyfin.Api.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager)
   at Jellyfin.Api.Middleware.IPBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Jellyfin.Api.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext)
   at Jellyfin.Api.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context)
   at Jellyfin.Api.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager)
   at Jellyfin.Api.Middleware.ExceptionMiddleware.Invoke(HttpContext context)
[2025-10-10 04:59:42.364 +00:00] [INF] [74] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.3" closed

🔄 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/14978 **Author:** [@theguymadmax](https://github.com/theguymadmax) **Created:** 10/11/2025 **Status:** ✅ Merged **Merged:** 10/12/2025 **Merged by:** [@joshuaboniface](https://github.com/joshuaboniface) **Base:** `master` ← **Head:** `fix-playlistfolder` --- ### 📝 Commits (1) - [`49c3443`](https://github.com/jellyfin/jellyfin/commit/49c3443b0cdf09b84aa644fe0438f6384aeb5623) Prevent PlaylistsFolder deletion during library removal ### 📊 Changes **1 file changed** (+6 additions, -0 deletions) <details> <summary>View changed files</summary> 📝 `MediaBrowser.Controller/Entities/Folder.cs` (+6 -0) </details> ### 📄 Description <!-- 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. --> After deleting any library, the PlaylistsFolder was also removed from the database, which would cause an exception if the user then tried to add an item to a playlist. **Changes** <!-- Describe your changes here in 1-5 sentences. --> Added `CanDelete()` check before deleting items in `ValidateChildrenInternal2` method **Issues** <!-- Tag any issues that this PR solves here. ex. Fixes # --> <details> <summary>Log Error</summary> ``` [2025-10-10 04:16:17.781 +00:00] [WRN] [99] MediaBrowser.Controller.Entities.BaseItem: Library folder "/config/data/playlists" is inaccessible or empty, skipping [2025-10-10 04:16:17.784 +00:00] [INF] [99] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "Folder", Name: "Movies 1", Path: "/MediaI/MediaI/Test Libraries/Movies/Movies 1", Id: bf40c806-c9af-07b6-1530-b34546e524de [2025-10-10 04:16:18.373 +00:00] [INF] [99] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "PlaylistsFolder", Name: "Playlists", Path: "/config/data/playlists", Id: 1071671e-7bff-a053-2e93-0debee501d2e [2025-10-10 04:16:19.182 +00:00] [INF] [67] Emby.Server.Implementations.Library.LibraryManager: Removing item, Type: "CollectionFolder", Name: "Movies2", Path: "/config/root/default/Movies2", Id: 7f09ac8d-4f2f-9f30-6712-c0d21acd9863 [2025-10-10 04:16:19.546 +00:00] [INF] [99] Emby.Server.Implementations.Library.LibraryManager: Validating media library [2025-10-10 04:16:48.840 +00:00] [WRN] [31] MediaBrowser.Controller.Entities.BaseItem: Library folder "/config/data/playlists" is inaccessible or empty, skipping [2025-10-10 04:17:05.029 +00:00] [WRN] [96] MediaBrowser.Controller.Entities.BaseItem: Library folder "/config/data/playlists" is inaccessible or empty, skipping [2025-10-10 04:17:43.201 +00:00] [INF] [38] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.3" closed [2025-10-10 04:22:15.895 +00:00] [INF] [37] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.3" request [2025-10-10 04:22:43.914 +00:00] [INF] [70] Emby.Server.Implementations.ScheduledTasks.TaskManager: "Scan Media Library" Completed after 6 minute(s) and 24 seconds [2025-10-10 04:22:44.902 +00:00] [INF] [43] Emby.Server.Implementations.IO.LibraryMonitor: Watching directory "/MediaD/MediaD/Movies" [2025-10-10 04:55:24.407 +00:00] [INF] [94] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.3" request [2025-10-10 04:56:38.788 +00:00] [ERR] [29] Jellyfin.Api.Middleware.ExceptionMiddleware: Error processing request. URL "POST" "/Playlists". System.ArgumentException: parentFolder at Emby.Server.Implementations.Playlists.PlaylistManager.CreatePlaylist(PlaylistCreationRequest request) at Jellyfin.Api.Controllers.PlaylistsController.CreatePlaylist(String name, IReadOnlyList`1 ids, Nullable`1 userId, Nullable`1 mediaType, CreatePlaylistDto createPlaylistRequest) at lambda_method360482(Closure, Object) at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(ActionContext actionContext, IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync() --- End of stack trace from previous location --- at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope) at Jellyfin.Api.Middleware.ServerStartupMessageMiddleware.Invoke(HttpContext httpContext, IServerApplicationHost serverApplicationHost, ILocalizationManager localizationManager) at Jellyfin.Api.Middleware.WebSocketHandlerMiddleware.Invoke(HttpContext httpContext, IWebSocketManager webSocketManager) at Jellyfin.Api.Middleware.IPBasedAccessValidationMiddleware.Invoke(HttpContext httpContext, INetworkManager networkManager) at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context) at Jellyfin.Api.Middleware.QueryStringDecodingMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.ReDoc.ReDocMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext) at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider) at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context) at Jellyfin.Api.Middleware.RobotsRedirectionMiddleware.Invoke(HttpContext httpContext) at Jellyfin.Api.Middleware.LegacyEmbyRouteRewriteMiddleware.Invoke(HttpContext httpContext) at Microsoft.AspNetCore.ResponseCompression.ResponseCompressionMiddleware.InvokeCore(HttpContext context) at Jellyfin.Api.Middleware.ResponseTimeMiddleware.Invoke(HttpContext context, IServerConfigurationManager serverConfigurationManager) at Jellyfin.Api.Middleware.ExceptionMiddleware.Invoke(HttpContext context) [2025-10-10 04:59:42.364 +00:00] [INF] [74] Emby.Server.Implementations.HttpServer.WebSocketManager: WS "192.168.1.3" closed ``` </details> --- <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:26:13 +03:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/jellyfin#14209