From 7dfa30a151a0c709723441d09185ee68fe7d9dd0 Mon Sep 17 00:00:00 2001 From: 0xsysr3ll <31414959+0xSysR3ll@users.noreply.github.com> Date: Tue, 28 Oct 2025 17:25:57 +0100 Subject: [PATCH] fix(media): handle 4K Radarr removal for multiple instances (#2037) This PR fixes an issue where removing 4K movies from Radarr failed when multiple Radarr instances were configured. The backend was misparsing boolean query parameters and using string slugs instead of TMDB IDs. The fix ensures that the correct 4K Radarr instance is targeted and that TMDB IDs are used for movie removal. Signed-off-by: 0xsysr3ll <0xsysr3ll@pm.me> --- server/routes/media.ts | 23 ++++++++------------ src/components/ManageSlideOver/index.tsx | 27 +++++++++++++++++++++++- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/server/routes/media.ts b/server/routes/media.ts index f4fc878bd..a3a97c13d 100644 --- a/server/routes/media.ts +++ b/server/routes/media.ts @@ -112,7 +112,7 @@ mediaRoutes.post< return next({ status: 404, message: 'Media does not exist.' }); } - const is4k = Boolean(req.body.is4k); + const is4k = String(req.body.is4k) === 'true'; switch (req.params.status) { case 'available': @@ -198,7 +198,7 @@ mediaRoutes.delete( where: { id: Number(req.params.id) }, }); - const is4k = req.query.is4k === 'true'; + const is4k = String(req.query.is4k) === 'true'; const isMovie = media.mediaType === MediaType.MOVIE; let serviceSettings; @@ -212,18 +212,19 @@ mediaRoutes.delete( ); } + const specificServiceId = is4k ? media.serviceId4k : media.serviceId; if ( - media.serviceId && - media.serviceId >= 0 && - serviceSettings?.id !== media.serviceId + specificServiceId && + specificServiceId >= 0 && + serviceSettings?.id !== specificServiceId ) { if (isMovie) { serviceSettings = settings.radarr.find( - (radarr) => radarr.id === media.serviceId + (radarr) => radarr.id === specificServiceId ); } else { serviceSettings = settings.sonarr.find( - (sonarr) => sonarr.id === media.serviceId + (sonarr) => sonarr.id === specificServiceId ); } } @@ -257,13 +258,7 @@ mediaRoutes.delete( } if (isMovie) { - await (service as RadarrAPI).removeMovie( - parseInt( - is4k - ? (media.externalServiceSlug4k as string) - : (media.externalServiceSlug as string) - ) - ); + await (service as RadarrAPI).removeMovie(media.tmdbId); } else { const tmdb = new TheMovieDb(); const series = await tmdb.getTvShow({ tvId: media.tmdbId }); diff --git a/src/components/ManageSlideOver/index.tsx b/src/components/ManageSlideOver/index.tsx index c1b115d41..7a2c1047e 100644 --- a/src/components/ManageSlideOver/index.tsx +++ b/src/components/ManageSlideOver/index.tsx @@ -150,6 +150,31 @@ const ManageSlideOver = ({ return false; }; + const isDefault4kService = () => { + if (data.mediaInfo) { + if (data.mediaInfo.mediaType === MediaType.MOVIE) { + return ( + radarrData?.find( + (radarr) => + radarr.isDefault && + radarr.is4k && + radarr.id === data.mediaInfo?.serviceId4k + ) !== undefined + ); + } else { + return ( + sonarrData?.find( + (sonarr) => + sonarr.isDefault && + sonarr.is4k && + sonarr.id === data.mediaInfo?.serviceId4k + ) !== undefined + ); + } + } + return false; + }; + const markAvailable = async (is4k = false) => { if (data.mediaInfo) { await axios.post(`/api/v1/media/${data.mediaInfo?.id}/available`, { @@ -572,7 +597,7 @@ const ManageSlideOver = ({ - {isDefaultService() && ( + {isDefault4kService() && (
deleteMediaFile(true)}