BeyondDimension/SteamTools · warning · ApplicationException
no serial_number
Error message
no serial_number
What it means
Thrown during Steam Guard import when the deserialized SteamGuardModel has an empty/null SerialNumber. The serial is stored on the SteamAuthenticator and is needed for code generation/refresh, so its absence aborts import right after the shared-secret check.
Source
Thrown at src/BD.WTTS.Client.Plugins.Authenticator/UI/ViewModels/SteamGuardImportPageViewModel.cs:104
if (string.IsNullOrEmpty(deviceId) || DeviceIdRegex().IsMatch(deviceId) == false)
//WinAuthForm.ErrorDialog(this, "Invalid deviceid, expecting \"android:NNNN...\"");
return;
// check the steamguard
byte[] secret;
string? serial;
var steamGuardModel = SJsonSerializer.Deserialize(PhoneImportSteamGuard,
ImportFileModelJsonContext.Default.SteamGuardModel);
if (steamGuardModel == null) return;
if (string.IsNullOrEmpty(steamGuardModel.SharedSecret))
throw new ApplicationException("no shared_secret");
secret = Convert.FromBase64String(steamGuardModel.SharedSecret);
if (string.IsNullOrEmpty(steamGuardModel.SerialNumber))
throw new ApplicationException("no serial_number");
serial = steamGuardModel.SerialNumber;
var auth = new SteamAuthenticator
{
SecretKey = secret,
Serial = serial,
SteamData = PhoneImportSteamGuard,
DeviceId = deviceId,
};
await AuthenticatorHelper.SaveAuthenticator(new AuthenticatorDTO
{
Name = $"(Steam){ImportAuthNewName}",
Value = auth,
Created = DateTimeOffset.Now,
});
}View on GitHub (pinned to c16ffa08e0)
Solutions
- Re-export the Steam Guard data with the serial_number field populated.
- Copy the serial from the Steam mobile authenticator/account and add it to the JSON before import.
- Validate required fields up front and report all missing ones in one message.
- Reject the file in the UI with the specific missing field named.
Example fix
// before
if (string.IsNullOrEmpty(steamGuardModel.SerialNumber))
throw new ApplicationException("no serial_number");
// after
if (string.IsNullOrEmpty(steamGuardModel.SerialNumber))
throw new ArgumentException(Strings.Import_SteamMissingSerial); Defensive patterns
Strategy: validation
Validate before calling
if (string.IsNullOrWhiteSpace(model.SerialNumber))
errors.Add("Steam Guard import missing 'serial_number'.");
// Combine with the shared_secret check so all missing fields are reported at once. Type guard
bool HasSerial(SteamGuardModel? m) => !string.IsNullOrWhiteSpace(m?.SerialNumber);
Try / catch
try { ImportSteamGuard(json); }
catch (ApplicationException ex) when (ex.Message == "no serial_number")
{
importErrors.Add("Steam Guard file lacks 'serial_number'.");
} Prevention
- Pre-validate the Steam Guard model fields and collect all missing ones before acting.
- Document the required Steam Guard JSON schema in the import UI.
- Reject files missing required fields with a clear list rather than throwing mid-import.
- Re-export from a source that includes both shared_secret and serial_number.
When it happens
Trigger: Importing a Steam Guard JSON blob where the 'serial_number' field is missing or empty, even though shared_secret was present.
Common situations: Export omitted the serial; JSON redacted/truncated; field renamed in a newer schema; partial manual edit of the export file.
Related errors
- no shared_secret
- Import only supports otpauth://
- Import only supports otpauth://totp/ or otpauth://hotp/
- Authenticator does not contain secret
- HOTP authenticator should have a counter
AI-assisted analysis of BeyondDimension/SteamTools@c16ffa08e0 (2026-08-13).
Data as JSON: /api/errors/ad5caf8eaa723049.
Report an issue: GitHub.