{"record":{"id":"e60099529b6a9161","repo":"BeyondDimension/SteamTools","slug":"invalid-serial-for-battle-net-authenticator","errorCode":null,"errorMessage":"Invalid serial for Battle.net Authenticator","messagePattern":"Invalid serial for Battle\\.net Authenticator","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"warning","filePath":"src/BD.WTTS.Client.Plugins.Authenticator/UI/ViewModels/AuthenticatorImportPageViewModel.cs","lineNumber":317,"sourceCode":"                {\n                    throw new ApplicationException(\"HOTP authenticator should have a counter\");\n                }\n\n                AuthenticatorDTO authenticatorDto = new();\n\n                AuthenticatorValueDTO auth;\n                if (string.Compare(issuer, \"BattleNet\", StringComparison.OrdinalIgnoreCase) == 0)\n                {\n                    string? serial = query[\"serial\"];\n                    if (string.IsNullOrEmpty(serial))\n                    {\n                        throw new ApplicationException(\"Battle.net Authenticator does not have a serial\");\n                    }\n\n                    serial = serial.ToUpper();\n                    if (Regex.IsMatch(serial, @\"^[A-Z]{2}-?[\\d]{4}-?[\\d]{4}-?[\\d]{4}$\") == false)\n                    {\n                        throw new ApplicationException(\"Invalid serial for Battle.net Authenticator\");\n                    }\n\n                    auth = new BattleNetAuthenticator();\n                    //char[] decoded = Base32.getInstance().Decode(secret).Select(c => Convert.ToChar(c)).ToArray(); // this is hex string values\n                    //string hex = new string(decoded);\n                    //((BattleNetAuthenticator)auth).SecretKey = Authenticator.StringToByteArray(hex);\n\n                    ((BattleNetAuthenticator)auth).SecretKey = Base32.GetInstance().Decode(secret);\n\n                    ((BattleNetAuthenticator)auth).Serial = serial;\n\n                    issuer = string.Empty;\n                }\n                else if (string.Compare(issuer, \"Steam\", StringComparison.OrdinalIgnoreCase) == 0)\n                {\n                    auth = new SteamAuthenticator();\n                    ((SteamAuthenticator)auth).SecretKey = Base32.GetInstance().Decode(secret);\n                    ((SteamAuthenticator)auth).Serial = string.Empty;","sourceCodeStart":299,"sourceCodeEnd":335,"githubUrl":"https://github.com/BeyondDimension/SteamTools/blob/c16ffa08e03b192d23ada290c4969e77f9201f3d/src/BD.WTTS.Client.Plugins.Authenticator/UI/ViewModels/AuthenticatorImportPageViewModel.cs#L299-L335","documentation":"Thrown when a Battle.net serial fails the format regex ^[A-Z]{2}-?[\\d]{4}-?[\\d]{4}-?[\\d]{4}$ (after uppercasing). The serial must be two letters followed by three groups of four digits, with optional dashes; anything else is treated as invalid.","triggerScenarios":"Importing a BattleNet entry whose serial, after ToUpper, does not match the expected two-letters + 12-digits pattern (dashes optional).","commonSituations":"Serial mistyped or truncated; serial copied with extra characters/spaces; serial from a different/legacy format; regional serial format that doesn't fit the pattern.","solutions":["Re-copy the serial exactly as shown in the Battle.net authenticator (US-XX-XXXX-XXXX-XXXX style).","Strip spaces and ensure only letters/digits/dashes remain before validating.","If the genuine serial uses a different format, extend the regex rather than forcing the value.","Show the expected format in the UI error so the user can self-correct."],"exampleFix":"// before\nserial = serial.ToUpper();\nif (Regex.IsMatch(serial, @\"^[A-Z]{2}-?[\\d]{4}-?[\\d]{4}-?[\\d]{4}$\") == false)\n    throw new ApplicationException(\"Invalid serial for Battle.net Authenticator\");\n\n// after: normalise dashes/spaces, then a clearer message\nserial = serial.ToUpper().Replace(\" \", \"\");\nif (!Regex.IsMatch(serial, @\"^[A-Z]{2}-?\\d{4}-?\\d{4}-?\\d{4}$\"))\n    throw new ArgumentException(string.Format(Strings.Import_BadBattleNetSerial, serial));","handlingStrategy":"validation","validationCode":"static readonly Regex BattleNetSerial =\n    new(@\"^[A-Z]{2}-?\\d{4}-?\\d{4}-?\\d{4}$\", RegexOptions.Compiled);\n\nbool IsValidBattleNetSerial(string? serial)\n    => !string.IsNullOrWhiteSpace(serial) && BattleNetSerial.IsMatch(serial.Trim().ToUpperInvariant());\n\nif (issuer.Equals(\"BattleNet\", StringComparison.OrdinalIgnoreCase) && !IsValidBattleNetSerial(query[\"serial\"]))\n    errors.Add(($\"Line {n}: serial format invalid (expected US-XXXX-XXXX-XXXX).\", line));","typeGuard":"bool IsValidSerial(string? s) => !string.IsNullOrWhiteSpace(s) && Regex.IsMatch(s.Trim().ToUpperInvariant(), @\"^[A-Z]{2}-?\\d{4}-?\\d{4}-?\\d{4}$\");","tryCatchPattern":"try { ParseAuthenticator(line); }\ncatch (ApplicationException ex) when (ex.Message == \"Invalid serial for Battle.net Authenticator\")\n{\n    importErrors.Add(($\"Bad Battle.net serial format (line {n}). Expected US-XXXX-XXXX-XXXX.\", line));\n    continue;\n}","preventionTips":["Normalize the serial (trim, uppercase, strip spaces) before validating.","Show the expected format mask in the UI next to the serial field.","Extend the regex if genuine serials use a different region format, rather than rejecting them.","Report the offending value (truncated) in the error so the user can compare."],"tags":["authenticator","import","validation","battlenet","regex"],"backgroundTag":null,"analyzedSha":"c16ffa08e03b192d23ada290c4969e77f9201f3d","analyzedAt":"2026-08-13T11:52:20.410Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}