diff --git a/internal/arrs/registrar/manager.go b/internal/arrs/registrar/manager.go index 5f0a37e4e..fcd13adc6 100644 --- a/internal/arrs/registrar/manager.go +++ b/internal/arrs/registrar/manager.go @@ -14,6 +14,12 @@ import ( "golift.io/starr/sonarr" ) +// AltmountDownloadClientName is the name AltMount registers itself under as a +// SABnzbd-compatible download client in Radarr/Sonarr/Lidarr/etc. Other code +// (e.g. the queue cleanup worker) imports this to distinguish AltMount's own +// queue items from those owned by other download clients. +const AltmountDownloadClientName = "AltMount (SABnzbd)" + type Manager struct { instances *instances.Manager clients *clients.Manager @@ -366,7 +372,7 @@ func (m *Manager) EnsureWebhookRegistration(ctx context.Context, altmountURL str // EnsureDownloadClientRegistration ensures that AltMount is registered as a SABnzbd download client in all enabled ARR instances func (m *Manager) EnsureDownloadClientRegistration(ctx context.Context, altmountHost string, altmountPort int, urlBase string, apiKey string) error { allInstances := m.instances.GetAllInstances() - clientName := "AltMount (SABnzbd)" + clientName := AltmountDownloadClientName slog.InfoContext(ctx, "Ensuring AltMount download client registration in ARR instances", "host", altmountHost, diff --git a/internal/arrs/worker/worker.go b/internal/arrs/worker/worker.go index 2778a8552..e16caa865 100644 --- a/internal/arrs/worker/worker.go +++ b/internal/arrs/worker/worker.go @@ -13,6 +13,7 @@ import ( "github.com/javi11/altmount/internal/arrs/clients" "github.com/javi11/altmount/internal/arrs/instances" "github.com/javi11/altmount/internal/arrs/model" + "github.com/javi11/altmount/internal/arrs/registrar" "github.com/javi11/altmount/internal/config" "github.com/javi11/altmount/internal/database" "golift.io/starr" @@ -179,6 +180,13 @@ func (w *Worker) cleanupRadarrQueue(ctx context.Context, instance *model.ConfigI var idsToRemove []int64 for _, q := range queue.Records { + // Only operate on queue items owned by AltMount's registered download client. + // Items from other clients (qBittorrent, real SABnzbd, etc.) may reference + // paths AltMount cannot see and must never be touched — see issue #523. + if q.DownloadClient != registrar.AltmountDownloadClientName { + continue + } + // Strategy 1: Ghost detection — cleanup already-imported files if w.checkGhostByImportHistory(ctx, q.OutputPath, cfg, instance.Name, q.Title) { idsToRemove = append(idsToRemove, q.ID) @@ -301,6 +309,13 @@ func (w *Worker) cleanupSonarrQueue(ctx context.Context, instance *model.ConfigI var idsToRemove []int64 for _, q := range queue.Records { + // Only operate on queue items owned by AltMount's registered download client. + // Items from other clients (qBittorrent, real SABnzbd, etc.) may reference + // paths AltMount cannot see and must never be touched — see issue #523. + if q.DownloadClient != registrar.AltmountDownloadClientName { + continue + } + // Strategy 1: Immediate cleanup for already imported files if w.checkGhostByImportHistory(ctx, q.OutputPath, cfg, instance.Name, q.Title) { idsToRemove = append(idsToRemove, q.ID)