{"record":{"id":"e9662a6550ec47fc","repo":"matryer/xbar","slug":"unarchive","errorCode":null,"errorMessage":"unarchive","messagePattern":"unarchive","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/update/update.go","lineNumber":224,"sourceCode":"\t\treturn errors.Wrap(err, \"get executable\")\n\t}\n\tappPath, err := appPathFromExecutable(executable)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"find app path\")\n\t}\n\tappPathDir := filepath.Dir(appPath)\n\tappPreviousPath := appPath + \".previous\"\n\terr = os.Rename(appPath, appPreviousPath)\n\tif err != nil {\n\t\t_, statErr := os.Stat(appPath)\n\t\t// not exist is ok, just ignore it\n\t\tif !os.IsNotExist(statErr) {\n\t\t\treturn errors.Wrap(err, \"rename existing app\")\n\t\t}\n\t}\n\terr = archiver.Unarchive(f.Name(), appPathDir)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"unarchive\")\n\t}\n\terr = os.RemoveAll(appPreviousPath)\n\tif err != nil {\n\t\treturn errors.Wrap(err, \"remove previous\")\n\t}\n\treturn nil\n}\n\n// Release is a GitHub release.\ntype Release struct {\n\tTagName         string    `json:\"tag_name\"`\n\tAssets          []Asset   `json:\"assets\"`\n\tBody            string    `json:\"body\"`\n\tCreatedAtString string    `json:\"created_at\"`\n\tCreatedAt       time.Time `json:\"created_at_time\"`\n}\n\n// Asset is a file within a Release on GitHub.","sourceCodeStart":206,"sourceCodeEnd":242,"githubUrl":"https://github.com/matryer/xbar/blob/d624239058997c80118eaebe2e7f8331b3c765e0/pkg/update/update.go#L206-L242","documentation":"Raised in Updater.downloadAndReplaceApp when archiver.Unarchive fails to extract the downloaded update archive into the app's directory. By this point the running app has already been renamed to the '.previous' path, so a failure here leaves the installation in a swapped-out state: the old build exists only under appPath + '.previous' and the update is not applied.","triggerScenarios":"Calling Update() when the downloaded asset is a corrupt/truncated zip, is not actually a zip despite the extension, contains files with paths the extractor can't write (permissions, existing locked files), or the zip uses unsupported compression/encryption.","commonSituations":"Download interrupted earlier producing a partial zip; server returned an HTML error page saved with a .zip name; extracting over files locked by running processes on Windows; zips created with encryption or non-deflate compression.","solutions":["Verify the downloaded archive is complete and not corrupted (check size/hash before unarchiving)","Confirm the archive format is one the archiver library supports","Check write permissions and free disk space in appPathDir","On failure, restore the app by renaming the '.previous' copy back to appPath so the old version still runs","Re-download the archive if it was truncated or tampered with"],"exampleFix":null,"handlingStrategy":"fallback","validationCode":"zr, err := zip.OpenReader(downloadedZipPath)\nif err != nil {\n\treturn fmt.Errorf(\"downloaded asset is not a valid zip: %w\", err)\n}\nzr.Close()","typeGuard":null,"tryCatchPattern":"err := u.Update()\nif err != nil && strings.Contains(err.Error(), \"unarchive\") {\n\tlog.Printf(\"update archive invalid; re-downloading: %v\", err)\n\treturn retryUpdate()\n}","preventionTips":["Verify archive integrity (checksum) at publish time and after download","Publish zips with standard deflate compression, no encryption","Ensure no other processes lock files in the extraction directory"],"tags":["zip","unarchive","corrupt-file"],"backgroundTag":"archive-extraction-failed","analyzedSha":"d624239058997c80118eaebe2e7f8331b3c765e0","analyzedAt":"2026-09-02T22:38:22.007Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-10T02:17:09.455Z"}