{"record":{"id":"18c781761f7e91a4","repo":"LykosAI/StabilityMatrix","slug":"archive-must-be-a-zipped-tar","errorCode":null,"errorMessage":"Archive must be a zipped tar.","messagePattern":"Archive must be a zipped tar\\.","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"StabilityMatrix.Core/Helper/ArchiveHelper.cs","lineNumber":183,"sourceCode":"        }\n        catch (Exception e)\n        {\n            throw new Exception($\"Could not parse 7z output [{e.Message}]: {output.ToRepr()}\");\n        }\n    }\n\n    /// <summary>\n    /// Extracts a zipped tar (i.e. '.tar.gz') archive.\n    /// First extracts the zipped tar, then extracts the tar and removes the tar.\n    /// </summary>\n    /// <param name=\"archivePath\"></param>\n    /// <param name=\"extractDirectory\"></param>\n    /// <returns></returns>\n    public static async Task<ArchiveInfo> Extract7ZTar(string archivePath, string extractDirectory)\n    {\n        if (!archivePath.EndsWith(\".tar.gz\"))\n        {\n            throw new ArgumentException(\"Archive must be a zipped tar.\");\n        }\n        // Extract the tar.gz to tar\n        await Extract7Z(archivePath, extractDirectory).ConfigureAwait(false);\n\n        // Extract the tar\n        var tarPath = Path.Combine(extractDirectory, Path.GetFileNameWithoutExtension(archivePath));\n        if (!File.Exists(tarPath))\n        {\n            throw new FileNotFoundException(\"Tar file not found.\", tarPath);\n        }\n\n        try\n        {\n            return await Extract7Z(tarPath, extractDirectory).ConfigureAwait(false);\n        }\n        finally\n        {\n            // Remove the tar","sourceCodeStart":165,"sourceCodeEnd":201,"githubUrl":"https://github.com/LykosAI/StabilityMatrix/blob/af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002/StabilityMatrix.Core/Helper/ArchiveHelper.cs#L165-L201","documentation":"Extract7ZTar requires the archive path to end with '.tar.gz'. This guard throws ArgumentException before doing any work when the extension doesn't match, because the two-pass extraction (gz then tar) only makes sense for zipped tars.","triggerScenarios":"Calling Extract7ZTar with a path not ending in '.tar.gz' — e.g. '.tgz', '.tar.bz2', '.zip', or a URL-derived filename without the extension.","commonSituations":"Download code saving a '.tgz' file (a valid gzipped tar) but passing it to Extract7ZTar, which only accepts the literal '.tar.gz' suffix; passing extracted-directory filenames stripped of their double extension.","solutions":["Rename/normalize the archive to a '.tar.gz' extension before calling Extract7ZTar, or map '.tgz' to it","Use Extract7ZAuto instead, which dispatches on the archive type automatically","Check the downloaded file's actual extension/content type before choosing the extraction method"],"exampleFix":"// before\nawait ArchiveHelper.Extract7ZTar(archivePath, destDir); // archivePath = \"foo.tgz\"\n// after\nif (archivePath.EndsWith(\".tgz\"))\n    archivePath = Path.ChangeExtension(archivePath, \".tar.gz\"); // after renaming on disk\nawait ArchiveHelper.Extract7ZAuto(archivePath, destDir);","handlingStrategy":"validation","validationCode":"if (!archivePath.EndsWith(\".tar.gz\", StringComparison.OrdinalIgnoreCase))\n    throw new ArgumentException($\"Extract7ZTar requires .tar.gz, got: {archivePath}\");","typeGuard":"static bool IsZippedTarPath(string p) =>\n    p.EndsWith(\".tar.gz\", StringComparison.OrdinalIgnoreCase);","tryCatchPattern":"try { await ArchiveHelper.Extract7ZTar(archivePath, destDir); }\ncatch (ArgumentException ex)\n{\n    logger.LogWarning(ex, \"Not a .tar.gz; falling back to Extract7ZAuto\");\n    await ArchiveHelper.Extract7ZAuto(archivePath, destDir);\n}","preventionTips":["Dispatch on extension before choosing the extractor","Normalize '.tgz' to '.tar.gz' (rename) after download","Prefer Extract7ZAuto for unknown archive types","Validate downloaded filenames against expected patterns"],"tags":["archive","argument","tar","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"af93d6ef57c01cd890d7e0ad0a9ea8c9fcda3002","analyzedAt":"2026-09-12T19:02:43.389Z","contentChangedAt":"2026-09-12T19:02:43.389Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}