{"record":{"id":"2f7efa0345602383","repo":"netchx/netch","slug":"update-file-top-level-directory-not-exist","errorCode":null,"errorMessage":"Update file top-level directory not exist","messagePattern":"Update file top-level directory not exist","errorType":"exception","errorClass":"MessageException","httpStatus":null,"severity":"error","filePath":"Netch/Services/Updater.cs","lineNumber":42,"sourceCode":"        _tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());\n\n        Directory.CreateDirectory(_tempDirectory);\n    }\n\n    #region Apply Update\n\n    internal void ApplyUpdate()\n    {\n        var extractPath = Path.Combine(_tempDirectory, \"extract\");\n\n        int exitCode;\n        if ((exitCode = Extract(extractPath)) != 0)\n            throw new MessageException(i18N.Translate($\"7za unexpectedly exited. ({exitCode})\"));\n\n        // update archive file must have a top-level directory \"Netch\"\n        var updateDirectory = Path.Combine(extractPath, \"Netch\");\n        if (!Directory.Exists(updateDirectory))\n            throw new MessageException(i18N.Translate(\"Update file top-level directory not exist\"));\n\n        // {_tempDirectory}/extract/Netch/Netch.exe\n        var updateMainProgramFilePath = Path.Combine(updateDirectory, \"Netch.exe\");\n        if (!File.Exists(updateMainProgramFilePath))\n            throw new MessageException(i18N.Translate($\"Update file main program not exist\"));\n\n        MarkFilesOld();\n\n        // move {tempDirectory}\\extract\\Netch to install folder\n        MoveFilesOver(updateDirectory, InstallDirectory);\n    }\n\n    private void MarkFilesOld()\n    {\n        var keepDirFullPath = KeepDirectories.Select(d => Path.Combine(InstallDirectory, d)).ToImmutableList();\n\n        foreach (var file in Directory.GetFiles(InstallDirectory, \"*\", SearchOption.AllDirectories))\n        {","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/netchx/netch/blob/9d99eb1c5a2acbf2a34f2600f94242601019a300/Netch/Services/Updater.cs#L24-L60","documentation":"After a successful extraction the updater requires the archive to contain a single top-level directory named exactly 'Netch' (it does Path.Combine(extractPath, \"Netch\")). If that directory does not exist, the package layout is wrong and the update is aborted. This guard prevents files from being flattened directly into the install root, which would corrupt the install.","triggerScenarios":"The release archive was packaged without its 'Netch' root folder (files at archive root), or with a differently-named root directory (e.g. 'Netch-x64', 'netch', or a version-numbered folder).","commonSituations":"Maintainer repackaged the release incorrectly; the updater was pointed at a third-party or wrong archive; a cross-platform packaging step produced a versioned folder name.","solutions":["Use the official update package whose top-level folder is 'Netch'.","Re-download from the official source.","If building locally, ensure the archive root directory is named 'Netch'.","Open the archive with 7-Zip/Explorer to confirm the folder layout before applying."],"exampleFix":"// before\nvar updateDirectory = Path.Combine(extractPath, \"Netch\");\nif (!Directory.Exists(updateDirectory))\n    throw new MessageException(i18N.Translate(\"Update file top-level directory not exist\"));\n// after - accept the single top-level dir, or require the 'Netch' name\nvar topDirs = Directory.GetDirectories(extractPath);\nvar updateDirectory = topDirs.Length == 1 ? topDirs[0] : Path.Combine(extractPath, \"Netch\");\nif (!Directory.Exists(updateDirectory))\n    throw new MessageException(\"Update archive must contain a top-level 'Netch' directory\");","handlingStrategy":"validation","validationCode":"// After extraction, sanity-check the layout\nvar root = Path.Combine(extractPath, \"Netch\");\nif (!Directory.Exists(root))\n    throw new MessageException(\"Update package layout invalid; expected a top-level 'Netch' folder.\");","typeGuard":null,"tryCatchPattern":"try { updater.ApplyUpdate(); }\ncatch (MessageException ex) when (ex.Message.Contains(\"top-level directory\"))\n{\n    Log.Error(\"Bad update package layout: {Msg}\", ex.Message);\n    Global.MainForm.NotifyTip(\"This update package is malformed. Use the official release.\");\n}","preventionTips":["In the release script, assert the archive's first entry is a 'Netch' directory.","Document the required archive layout for contributors.","Add a CI check that opens the published archive and verifies the root folder name."],"tags":["updater","archive","install","packaging"],"backgroundTag":null,"analyzedSha":"9d99eb1c5a2acbf2a34f2600f94242601019a300","analyzedAt":"2026-08-13T14:12:19.105Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}