fix(arrs): route multi-instance categories like radarr-abc to the correct ARR type#674
Open
samtheruby wants to merge 1 commit into
Open
fix(arrs): route multi-instance categories like radarr-abc to the correct ARR type#674samtheruby wants to merge 1 commit into
samtheruby wants to merge 1 commit into
Conversation
…rrect ARR type Fix the "could not determine ARR type for category: <name>" post-process notification failure when users run multiple ARR instances with suffixed categories (e.g. radarr-sqp1, sonarr-4k, sonarr-anime). Three complementary changes: 1. Heuristic (config.InferARRTypeFromCategory): switched the fallback rules from exact equality (category == "radarr") to strings.HasPrefix so any name beginning with "radarr"/"sonarr"/"lidarr"/"readarr"/"whisparr" routes correctly. Moved the helper from internal/importer/postprocessor into internal/config so the startup migration below can reuse it without creating an import cycle. 2. Instance manager: threaded arrType through ensureCategoryExistsInConfig so newly-created SAB categories have the Type field set from the start. Also backfills Type on a previously-created category whose Type was left empty. 3. Startup migration (config.MigrateCategoryTypes): on every LoadConfig, walk SABnzbd.Categories and fill any empty Type using the heuristic. When something changes, write a .bak alongside config.yaml and persist the updated file. This handles every existing install on first run without forcing users to edit yaml or re-add ARR instances. Existing user-set Type values are preserved. The runtime heuristic in arr_notifier remains as a defence-in-depth fallback for any category whose Type couldn't be resolved at load time.
1a4f140 to
97fb481
Compare
javi11
reviewed
Jun 13, 2026
| // inferARRTypeFromCategory is a thin shim around config.InferARRTypeFromCategory | ||
| // kept so the existing table-driven test in this package continues to compile. | ||
| // Prefer calling config.InferARRTypeFromCategory directly from new code. | ||
| func inferARRTypeFromCategory(categoryName string) string { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Note
This PR was authored with AI (Claude Code). All code reviewed by a human before submission. Tests written and verified locally.
Summary
Fixes the
could not determine ARR type for category: <name>post-process notification failure when users run multiple ARR instances with suffixed categories (e.g.radarr-abc,sonarr-4k,sonarr-anime).Three complementary changes:
Heuristic (
internal/config/manager.go: InferARRTypeFromCategory) — switched the fallback rules from exact equality (category == "radarr") tostrings.HasPrefix, so any name beginning withradarr/sonarr/lidarr/readarr/whisparrroutes correctly. Helper now lives ininternal/configso the startup migration below can reuse it without creating an import cycle (internal/arrsalready importsinternal/config).internal/importer/postprocessor/arr_notifier.gocalls the helper via the config package.Instance manager (
internal/arrs/instances/manager.go) — threadedarrTypethroughensureCategoryExistsInConfigso newly-created SAB categories have theTypefield set from the start, and added a backfill that fillsTypeon a previously-created category whoseTypewas left empty when an ARR instance is (re-)registered.Startup migration (
internal/config/manager.go: MigrateCategoryTypes) — on everyLoadConfig, walkSABnzbd.Categoriesand fill any emptyTypeusing the heuristic. When something changes, write a.baknext toconfig.yamland persist the updated file. Handles every existing install on first run without forcing users to edit yaml or re-add ARR instances. User-setTypevalues are never overwritten; names that don't match the heuristic are left alone.The runtime heuristic in
arr_notifier.gostays in place as a defence-in-depth fallback for any category whoseTypecouldn't be resolved at load time.Why this matters
SABnzbdCategory.Typeis honored byarr_notifier.gobut is not exposed in the frontend SAB config form (frontend/src/components/config/SABnzbdConfigSection.tsxonly editsname/order/priority/dir). Before this PR, the only ways to setTypewere editingconfig.yamlby hand, or hoping your category name was literallyradarr/sonarr/ containedmovieortv. Multi-instance setups (one Radarr per quality profile, etc.) all hit the failure mode.The startup migration means existing affected installs are auto-healed the first time they boot a build that includes this PR — no manual yaml editing required, and the
.baklets users revert if they don't like the change.Test plan
go test ./internal/config/—InferARRTypeFromCategory(17 cases) +MigrateCategoryTypes(backfill, preserves-user-set, skips-unknown, no-categories). All pass.go test ./internal/importer/postprocessor/— 26-case table-driven test for the heuristic via the postprocessor shim, covering all suffixed names plus the existing keyword cases. All pass.go test ./internal/arrs/instances/— 4 cases forensureCategoryExistsInConfig: new-category-sets-type, backfills-empty-type-on-existing, preserves-user-set-type, empty-name-defaults-to-default-with-type. All pass.go vet ./...— clean.go build ./...— clean.Type. Confirm theINFO Backfilled SABnzbd category types from heuristic categories=[...] count=Nlog line on first start,config.yaml.bakis written, and post-process notification fires (nocould not determine ARR typelog).radarr-abc), confirm the SABnzbd category getstype: radarrwritten from the start.