beeradmoore/dlss-swapper · error · Exception

Unknown GameLibrary while setting ID

Error message

Unknown GameLibrary {GameLibrary} while setting ID

What it means

Game.SetID builds a prefixed string id (e.g. "steam_1234") via a switch expression over the GameLibrary enum. Every supported library is listed, so the default arm only fires when GameLibrary holds a value the switch does not know - an enum member added later or a value from a persisted settings file that predates/current code does not recognize.

Solutions

  1. Add the missing GameLibrary member to the switch expression in SetID with its correct id prefix (follow the existing "$prefix_{platformId}" pattern).
  2. Audit the GameLibrary enum: every member must be handled in SetID's switch expression.
  3. If the value came from persisted data, fix/refresh the stored game entry and add validation when loading GameLibrary values from disk.
  4. Check for enum values added by a newer app version being read by an older binary; align app and data versions.

Example fix

// before
GameLibrary.EAApp => $"eaapp_{platformId}",
_ => throw new Exception($"Unknown GameLibrary {GameLibrary} while setting ID"),
// after
GameLibrary.EAApp => $"eaapp_{platformId}",
GameLibrary.Steam => $"steam_{platformId}", // add any newly introduced member
_ => throw new InvalidOperationException($"Unknown GameLibrary {GameLibrary} while setting ID")
Defensive patterns

Strategy: validation

Validate before calling

// Validate enum value before calling SetID
if (Enum.IsDefined(typeof(GameLibrary), game.GameLibrary) == false ||
    game.GameLibrary is GameLibrary.Unknown)
{
    throw new ArgumentException($"GameLibrary value {game.GameLibrary} is not supported");
}

Type guard

bool IsSupportedLibrary(GameLibrary lib) =>
    lib is GameLibrary.Steam or GameLibrary.GOG or GameLibrary.EpicGamesStore
         or GameLibrary.UbisoftConnect or GameLibrary.XboxApp or GameLibrary.ManuallyAdded
         or GameLibrary.BattleNet or GameLibrary.EAApp;

Try / catch

try
{
    game.SetID();
}
catch (Exception ex) when (ex.Message.StartsWith("Unknown GameLibrary"))
{
    logger.LogError(ex, "Unmapped GameLibrary {Lib}; skipping game", game.GameLibrary);
}

Prevention

When it happens

Trigger: SetID is called with a Game whose GameLibrary property is an unmapped enum value: a newly added GameLibrary member missing from the switch, or a stale/int value loaded from the database or settings that maps to an undefined/unsupported library.

Common situations: Upgrading DLSS Swapper after a new store launcher (new GameLibrary member) was added to the enum but not to SetID's switch; corrupt or hand-edited config storing an out-of-range GameLibrary integer.

Related errors


AI-assisted analysis of beeradmoore/dlss-swapper@ab9b1e2d4b (2026-09-15). Data as JSON: /api/errors/6d91e59bc9b50ec4. Report an issue: GitHub.

Appendix: source

Thrown at src/Data/Game.cs:233

        foreach (var invalidPathChar in PathHelpers.InvalidFileNamePathChars)
        {
            if (platformId.Contains(invalidPathChar))
            {
                platformId = platformId.Replace(invalidPathChar, '_');
            }
        }

        ID = GameLibrary switch
        {
            GameLibrary.Steam => $"steam_{platformId}",
            GameLibrary.GOG => $"gog_{platformId}",
            GameLibrary.EpicGamesStore => $"epicgamesstore_{platformId}",
            GameLibrary.UbisoftConnect => $"ubisoftconnect_{platformId}",
            GameLibrary.XboxApp => $"xboxapp_{platformId}",
            GameLibrary.ManuallyAdded => $"manuallyadded_{platformId}",
            GameLibrary.BattleNet => $"battlenet_{platformId}",
            GameLibrary.EAApp => $"eaapp_{platformId}",
            _ => throw new Exception($"Unknown GameLibrary {GameLibrary} while setting ID"),
        };
    }

    // Bounds how many games can be scanned for DLLs/covers at once. Every game with no previously known
    // DLLs is re-queued for processing on every launch, so without a limit a large library fires off
    // hundreds of concurrent recursive directory scans and UI-thread updates at startup.
    static readonly SemaphoreSlim processGameSemaphore = new SemaphoreSlim(4);

    /// <summary>
    /// Detects DLSS and updates cover image.
    /// </summary>
    public void ProcessGame(bool autoSave = true, bool forceNeedsProcessing = false)
    {
        // If we are alreayd procssing we don't need to process again
        if (Processing == true)
        {
            return;
        }

View on GitHub (pinned to ab9b1e2d4b)