{"record":{"id":"913b39e7ec5b1ca5","repo":"beeradmoore/dlss-swapper","slug":"could-not-find-dll-in-zip","errorCode":null,"errorMessage":"Could not find dll in zip.","messagePattern":"Could not find dll in zip\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/Data/DLLManager.cs","lineNumber":1392,"sourceCode":"\n    /// <summary>\n    /// This handles extracting of the DLL from both downloaded and imported zips (when imported matches the hash of one that could be downloaded)\n    /// </summary>\n    /// <param name=\"zipArchive\"></param>\n    /// <param name=\"dllRecord\"></param>\n    /// <exception cref=\"Exception\"></exception>\n    internal static void HandleExtractFromZip(ZipArchive zipArchive, DLLRecord dllRecord)\n    {\n        if (dllRecord.LocalRecord is null)\n        {\n            throw new Exception(\"LocalRecord was null when attempting to extract dll from zip.\");\n        }\n\n        var dllName = DLLManager.DllNameForGameAssetType(dllRecord.AssetType);\n        var entry = zipArchive.Entries.Single(x => x.Name.Equals(dllName, StringComparison.OrdinalIgnoreCase));\n        if (entry is null)\n        {\n            throw new Exception(\"Could not find dll in zip.\");\n        }\n        else\n        {\n            Storage.CreateDirectoryForFileIfNotExists(dllRecord.LocalRecord.ExpectedPath);\n            entry.ExtractToFile(dllRecord.LocalRecord.ExpectedPath, true);\n        }\n    }\n\n}\n","sourceCodeStart":1374,"sourceCodeEnd":1402,"githubUrl":"https://github.com/beeradmoore/dlss-swapper/blob/ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb/src/Data/DLLManager.cs#L1374-L1402","documentation":"After locating the DLL entry by name inside the downloaded zip, HandleExtractFromZip throws this if no archive entry matched the expected DLL name (DllNameForGameAssetType(assetType)). Note the code uses Single() on the entries, so this specific throw fires when the filter yields no match rather than multiple; it means the zip does not contain the DLL this record expects.","triggerScenarios":"Downloading a zip whose contents don't include the expected file name for the asset type — wrong/mismatched zip uploaded to the CDN, renamed DLL inside the archive, case/extension differences the OrdinalIgnoreCase Single() still misses (e.g. entry in a subfolder with different name), or AssetType not matching the package.","commonSituations":"Upstream release repackaged the zip and renamed the dll; manifest pointing at the wrong package URL; corrupted or partial download that is still a valid zip; fetching a universal zip that stores files under directories with different entry names.","solutions":["Verify the zip at the package URL actually contains the expected dll name for this asset type","Confirm ZipMD5Hash/URL in the manifest matches the current upstream package","Update DllNameForGameAssetType mapping if upstream renamed the DLL","Log the archive's entry names in the error to aid diagnosis"],"exampleFix":"// before\nvar entry = zipArchive.Entries.Single(x => x.Name.Equals(dllName, StringComparison.OrdinalIgnoreCase));\n// after\nvar entry = zipArchive.Entries.SingleOrDefault(x => x.Name.Equals(dllName, StringComparison.OrdinalIgnoreCase));\nif (entry is null)\n{\n    throw new Exception($\"Could not find '{dllName}' in zip. Entries: {string.Join(\", \", zipArchive.Entries.Select(e => e.FullName))}\");\n}","handlingStrategy":"try-catch","validationCode":"// after download, before extract\nusing var zip = new ZipArchive(zipStream);\nvar expected = DLLManager.DllNameForGameAssetType(assetType);\nif (!zip.Entries.Any(e => e.Name.Equals(expected, StringComparison.OrdinalIgnoreCase)))\n    throw new InvalidDataException($\"Package lacks {expected}.\");","typeGuard":"static ZipArchiveEntry? FindDllEntry(ZipArchive z, string dllName) =>\n    z.Entries.FirstOrDefault(e => e.Name.Equals(dllName, StringComparison.OrdinalIgnoreCase));","tryCatchPattern":"try\n{\n    HandleExtractFromZip(zipArchive, dllRecord);\n}\ncatch (Exception ex) when (ex.Message.Contains(\"Could not find dll in zip\"))\n{\n    logger.LogError(ex, \"Package for {AssetType} is missing the expected DLL; re-download or update manifest.\", dllRecord.AssetType);\n}","preventionTips":["Validate MD5 (already enforced) and also sanity-check zip entries after download","Keep manifest zip URLs and hashes in sync with upstream releases","On failure, delete the cached zip so a fresh download is attempted","Log entry names to detect upstream renames quickly"],"tags":["zip","file-not-found","download","dotnet"],"backgroundTag":"resource-not-found","analyzedSha":"ab9b1e2d4bb04187c48fe58eeea06c2b0ea71fbb","analyzedAt":"2026-09-15T05:25:32.979Z","contentChangedAt":"2026-09-15T05:25:32.979Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}