The bug
SABnzbd silently reassigns jobs with unknown categories to Default (*). Listenarr sends cat=<configured> on add, but every read mapper filtered slots by configured category before matching nzo_id (SabnzbdResponseMapper.MapQueueSlotToQueueItem / MapHistorySlotToQueueItem). So when the configured category doesn't exist in SABnzbd, a job Listenarr itself grabbed becomes invisible to it: the monitor reconciles by nzo_id but never sees the slot, the download shows "1 tracked but 0 in client", and it never progresses or imports. Notably the history endpoint is already fetched unfiltered — the recovery data was in hand and discarded client-side.
The fix
Two parts, mirroring how Radarr treats categories (reconcile items you grabbed by download ID; category scopes discovery, not tracked items):
- Tracked nzo_ids bypass the category filter. The fetch workflow already builds the monitored-id set; it now flows into both QueueItem mappers as an optional parameter, and a slot whose nzo_id is tracked is returned regardless of its category. Untracked discovery/display filtering is unchanged. (
MapQueueSlotToDownloadClientItemis deliberately untouched: the item-fetch path has no monitored set and isn't the strand path.) - Connection test warns about missing categories. After the version check passes, the tester probes
mode=get_catsand, if the configured category is absent, returns an advisory ("category 'x' does not exist in SABnzbd. Jobs will fall into Default and may not import. Create the category…") — still a passing test, and the probe is best-effort (any get_cats failure degrades to a clean pass).
Tests
QueueSlot_InDifferentCategory_ButTracked_IsReturned/HistorySlot_InDifferentCategory_ButTracked_IsReturnedQueueSlot_InDifferentCategory_NotTracked_IsFiltered/HistorySlot_InDifferentCategory_NotTracked_IsFiltered(discovery filtering preserved)- `TestConnection...
Automated Canary build