BeyondDimension/SteamTools · warning · ApplicationException

no shared_secret

Error message

no shared_secret

What it means

Thrown during Steam Guard (json) import when the deserialized SteamGuardModel has an empty/null SharedSecret. The shared secret is required to generate Steam TOTP codes locally, so without it the model cannot be turned into a SteamAuthenticator.

Source

Thrown at src/BD.WTTS.Client.Plugins.Authenticator/UI/ViewModels/SteamGuardImportPageViewModel.cs:99

                    return;
                }
            else
                deviceId = PhoneImportUuid;

            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
            {

View on GitHub (pinned to c16ffa08e0)

Solutions

  1. Re-export the Steam Guard data ensuring 'shared_secret' is included (it must come from a rooted device/official export).
  2. Confirm the selected JSON file is a Steam Guard export and not another authenticator's file.
  3. If shared_secret is genuinely unavailable, Steam TOTP cannot be reproduced locally — inform the user.
  4. Validate the field in the UI and list which required fields are missing.

Example fix

// before
if (string.IsNullOrEmpty(steamGuardModel.SharedSecret))
    throw new ApplicationException("no shared_secret");

// after: collect all missing fields, report once
var missing = new List<string>();
if (string.IsNullOrEmpty(steamGuardModel.SharedSecret)) missing.Add("shared_secret");
if (string.IsNullOrEmpty(steamGuardModel.SerialNumber)) missing.Add("serial_number");
if (missing.Count > 0)
    throw new ArgumentException($"Steam Guard import missing: {string.Join(", ", missing)}");
Defensive patterns

Strategy: validation

Validate before calling

var model = SJsonSerializer.Deserialize(json, ImportFileModelJsonContext.Default.SteamGuardModel);
if (model == null) { errors.Add("Steam Guard file is empty or unparseable."); return; }
if (string.IsNullOrWhiteSpace(model.SharedSecret))
    errors.Add("Steam Guard import missing 'shared_secret'.");

Type guard

bool HasSharedSecret(SteamGuardModel? m) => !string.IsNullOrWhiteSpace(m?.SharedSecret);

Try / catch

try { ImportSteamGuard(json); }
catch (ApplicationException ex) when (ex.Message == "no shared_secret")
{
    importErrors.Add("Steam Guard file lacks 'shared_secret'; cannot generate codes locally.");
}

Prevention

When it happens

Trigger: Importing a Steam Guard JSON blob (PhoneImportSteamGuard) where the 'shared_secret' field is absent or empty after deserialization.

Common situations: Export from a tool that only stored 'secret' (confidential) but not 'shared_secret'; JSON truncated/redacted; wrong file selected for import; Steam Guard model schema mismatch (field renamed).

Related errors


AI-assisted analysis of BeyondDimension/SteamTools@c16ffa08e0 (2026-08-13). Data as JSON: /api/errors/aa33a269c66b93ed. Report an issue: GitHub.