beeradmoore/dlss-swapper · error · Exception
LocalRecord was null when attempting to extract dll from…
Error message
LocalRecord was null when attempting to extract dll from zip.
What it means
HandleExtractFromZip requires a populated DLLRecord.LocalRecord because the extraction target path (LocalRecord.ExpectedPath) comes from it; when LocalRecord is null the record has never had local installation state computed, so extraction cannot proceed and the library throws. This is an internal precondition/invariant failure in the download-and-extract pipeline.
Solutions
- Initialize the DLLRecord's LocalRecord (expected path/registration) before extracting from the zip
- Ensure the asset type is present in the manager's local records before invoking extraction
- Guard the call site: skip or initialize records with null LocalRecord
Example fix
// before
HandleExtractFromZip(zipArchive, dllRecord);
// after
if (dllRecord.LocalRecord is null)
{
await dllRecord.InitializeLocalRecordAsync(); // or obtain record via manager lookup
}
HandleExtractFromZip(zipArchive, dllRecord); Defensive patterns
Strategy: type-guard
Validate before calling
// before extraction
if (dllRecord.LocalRecord is null)
await dllRecord.InitializeAsync(); // or fetch from manager registry Type guard
bool CanExtract(DLLRecord r) => r.LocalRecord?.ExpectedPath is not null;
Try / catch
try
{
HandleExtractFromZip(zipArchive, dllRecord);
}
catch (Exception ex) when (ex.Message.Contains("LocalRecord was null"))
{
logger.LogError(ex, "Record {AssetType} not initialized; re-registering.", dllRecord.AssetType);
} Prevention
- Always construct DLLRecords through the manager so LocalRecord is initialized
- Assert LocalRecord is non-null at record creation
- Don't persist/reuse records across app restarts without re-initializing local state
When it happens
Trigger: Calling HandleExtractFromZip (or the download/extract flow that leads to it) with a DLLRecord whose LocalRecord was never initialized — e.g. a record constructed without EnsureLocalRecord/initialization, or one built for an asset type the manager never registered locally.
Common situations: Manifest record deserialized without local state; calling extraction APIs directly on a fresh DLLRecord; asset type missing from the local records dictionary so lookup returned null.
Related errors
- Could not deserialize manifest.json.
- Unknown AssetType
- Could not find dll in zip.
- Could not download file.
AI-assisted analysis of beeradmoore/dlss-swapper@ab9b1e2d4b (2026-09-15).
Data as JSON: /api/errors/22b10f6c12ed98e1.
Report an issue: GitHub.
Appendix: source
Thrown at src/Data/DLLManager.cs:1385
GameAssetType.XeSS => "libxess.dll",
GameAssetType.XeSS_FG => "libxess_fg.dll",
GameAssetType.XeLL => "libxell.dll",
GameAssetType.XeSS_DX11 => "libxess_dx11.dll",
_ => string.Empty,
};
}
/// <summary>
/// This handles extracting of the DLL from both downloaded and imported zips (when imported matches the hash of one that could be downloaded)
/// </summary>
/// <param name="zipArchive"></param>
/// <param name="dllRecord"></param>
/// <exception cref="Exception"></exception>
internal static void HandleExtractFromZip(ZipArchive zipArchive, DLLRecord dllRecord)
{
if (dllRecord.LocalRecord is null)
{
throw new Exception("LocalRecord was null when attempting to extract dll from zip.");
}
var dllName = DLLManager.DllNameForGameAssetType(dllRecord.AssetType);
var entry = zipArchive.Entries.Single(x => x.Name.Equals(dllName, StringComparison.OrdinalIgnoreCase));
if (entry is null)
{
throw new Exception("Could not find dll in zip.");
}
else
{
Storage.CreateDirectoryForFileIfNotExists(dllRecord.LocalRecord.ExpectedPath);
entry.ExtractToFile(dllRecord.LocalRecord.ExpectedPath, true);
}
}
}
View on GitHub (pinned to ab9b1e2d4b)