{"record":{"id":"28d001781cb31311","repo":"Radarr/Radarr","slug":"quality-tag-is-not-in-the-correct-format","errorCode":null,"errorMessage":"Quality Tag is not in the correct format!","messagePattern":"Quality Tag is not in the correct format!","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"critical","filePath":"src/NzbDrone.Core/Datastore/Migration/168_custom_format_rework.cs","lineNumber":78,"sourceCode":"                }\n\n                updated.Add(new Specification168\n                {\n                    Id = row.Id,\n                    Specifications = specs\n                });\n            }\n\n            var updateSql = \"UPDATE \\\"CustomFormats\\\" SET \\\"Specifications\\\" = @Specifications WHERE \\\"Id\\\" = @Id\";\n            conn.Execute(updateSql, updated, transaction: tran);\n        }\n\n        public ICustomFormatSpecification ParseFormatTag(string raw)\n        {\n            var match = QualityTagRegex.Match(raw);\n            if (!match.Success)\n            {\n                throw new ArgumentException(\"Quality Tag is not in the correct format!\");\n            }\n\n            var result = InitializeSpecification(match);\n            result.Negate = match.Groups[\"m_n\"].Success;\n            result.Required = match.Groups[\"m_re\"].Success;\n\n            return result;\n        }\n\n        private ICustomFormatSpecification InitializeSpecification(Match match)\n        {\n            var type = match.Groups[\"type\"].Value.ToLower();\n            var value = match.Groups[\"value\"].Value.ToLower();\n            var isRegex = match.Groups[\"m_r\"].Success;\n\n            switch (type)\n            {\n                case \"r\":","sourceCodeStart":60,"sourceCodeEnd":96,"githubUrl":"https://github.com/Radarr/Radarr/blob/ca451608dc60c6cec754aba8d96bfa30e9468ed5/src/NzbDrone.Core/Datastore/Migration/168_custom_format_rework.cs#L60-L96","documentation":"ArgumentException thrown by ParseFormatTag during migration 168 (custom format rework). It migrates legacy quality tags into the new custom-format specification model using QualityTagRegex; if a stored quality tag does not match the expected regex grammar, migration aborts. Because this runs inside a DB migration, it blocks the upgrade.","triggerScenarios":"Migration 168 reads a legacy quality tag string from the old CustomFormats table whose format does not match QualityTagRegex (e.g. unknown prefix, malformed operator, or non-ASCII characters inserted by an old plugin/edit).","commonSituations":"Upgrading from a very old Radarr/Sonarr-derived install with hand-crafted quality tags; tags imported from a third-party profile; corrupted tag strings.","solutions":["Inspect the failing tag value (add temporary logging or read the row) and correct it to the documented quality-tag grammar before re-running migration 168.","Back up AppData, delete the offending CustomFormats row(s), and retry the upgrade.","Stay on the Radarr version whose schema matches your data, or export profiles and re-import after a clean DB.","File an issue with the exact tag string so the regex can be made more permissive."],"exampleFix":"// before: legacy tag that does not match QualityTagRegex\nvar tag = \"R_5.1+\"; // unexpected grammar\n\n// after: normalize to a supported tag shape before migration\nvar tag = \"R_5.1\";\n// or remove the legacy CustomFormats row causing the failure","handlingStrategy":"validation","validationCode":"// pre-migration: scan legacy quality tags against the regex\nvar regex = new Regex(QualityTagPattern); // same pattern as migration 168\nforeach (var tag in legacyTags)\n    if (!regex.IsMatch(tag))\n        throw new FormatException($\"Legacy quality tag '{tag}' will fail migration 168; fix or remove it.\");","typeGuard":"static bool IsValidQualityTag(string raw, Regex re) => re.IsMatch(raw);","tryCatchPattern":"// migrations run in a transaction; on failure, fix data and re-run\ntry { migrator.MigrateUp(); }\ncatch (ArgumentException ex) when (ex.Message.Contains(\"Quality Tag\"))\n{ /* identify offending row, normalize it, retry migration */ }","preventionTips":["Back up AppData before major upgrades so migration 168 can be re-run after data fixes.","Avoid hand-crafting quality tags in the legacy format.","Audit legacy CustomFormats rows for non-standard tag strings before upgrading."],"tags":["migration","custom-format","regex","database","upgrade"],"backgroundTag":null,"analyzedSha":"ca451608dc60c6cec754aba8d96bfa30e9468ed5","analyzedAt":"2026-08-13T17:21:54.115Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}