{"record":{"id":"4d3553ba67303945","repo":"hasura/graphql-engine","slug":"rename-old-to-exe-inconsistent-state-re-install","errorCode":null,"errorMessage":"rename old to exe: inconsistent state, re-install cli: %w","messagePattern":"rename old to exe: inconsistent state, re-install cli: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"cli/update/update.go","lineNumber":180,"sourceCode":"\terr = os.Rename(exe, oldExe)\n\tif err != nil {\n\t\treturn errors.E(op, fmt.Errorf(\"rename exe to old: %w\", err))\n\t}\n\n\t// rename the new binary as the current binary\n\terr = os.Rename(newExe, exe)\n\tif err != nil {\n\t\t// rename unsuccessful\n\t\t//\n\t\t// The filesystem is now in a bad state. We have successfully\n\t\t// moved the existing binary to a new location, but we couldn't move the new\n\t\t// binary to take its place. That means there is no file where the current executable binary\n\t\t// used to be!\n\t\t// Try to rollback by restoring the old binary to its original path.\n\t\trerr := os.Rename(oldExe, exe)\n\t\tif rerr != nil {\n\t\t\t// rolling back failed, ask user to re-install cli\n\t\t\treturn errors.E(op, fmt.Errorf(\n\t\t\t\t\"rename old to exe: inconsistent state, re-install cli: %w\",\n\t\t\t\trerr))\n\t\t}\n\t\t// rolled back, throw update error\n\t\treturn errors.E(op, fmt.Errorf(\"rename new to exe: %w\", err))\n\t}\n\n\t// rename success, remove the old binary\n\terrRemove := os.Remove(oldExe)\n\n\t// windows has trouble removing old binaries, so hide it instead\n\t// it will be removed next time this code runs.\n\tif errRemove != nil {\n\t\t_ = hideFile(oldExe)\n\t}\n\n\treturn nil\n}","sourceCodeStart":162,"sourceCodeEnd":198,"githubUrl":"https://github.com/hasura/graphql-engine/blob/724551b9ae87845594ef0408cff0e50eb6c90dc5/cli/update/update.go#L162-L198","documentation":"The worst-case self-update failure: the current binary was renamed to '<exe>.old', then renaming the new binary into place failed, and the rollback rename (old -> exe) ALSO failed (cli/update/update.go:180). The CLI is left with no executable at its expected path; the error explicitly tells the user to re-install because the updater cannot recover automatically.","triggerScenarios":"ApplyUpdate where the second os.Rename(newExe, exe) fails (e.g. the .new file disappeared or was quarantined by antivirus) and the subsequent os.Rename(oldExe, exe) also fails (permissions changed, disk error, locked files).","commonSituations":"Antivirus quarantining the freshly downloaded .new binary mid-swap; disk filling or permissions changing between the two renames; power loss or forced process kill during the swap window leaving an inconsistent state.","solutions":["Re-install the CLI using your original install method (install script, package manager, go install) — recovery by hand is only for experts.","As a last resort, manually restore: mv '<exe>.old' back to the exe path if the .old file still exists.","On Windows, exclude the CLI install directory from real-time antivirus scanning before updating again.","Ensure stable permissions and disk space before retrying updates."],"exampleFix":"# recovery when .old survived\n$ ls /usr/local/bin/cli*  # see cli.old / .cli.new\n$ mv /usr/local/bin/cli.old /usr/local/bin/cli\n$ chmod +x /usr/local/bin/cli\n# then re-install properly","handlingStrategy":"fallback","validationCode":"if _, err := os.Stat(exe); err != nil {\n    if _, oerr := os.Stat(exe + \".old\"); oerr == nil {\n        // recovery possible: .old exists\n    }\n}","typeGuard":null,"tryCatchPattern":"if err := update.ApplyUpdate(v); err != nil {\n    if strings.Contains(err.Error(), \"inconsistent state, re-install cli\") {\n        os.Rename(exe+\".old\", exe) // best-effort manual recovery\n        return fmt.Errorf(\"update broke install; restored from .old, please re-install: %w\", err)\n    }\n    return err\n}","preventionTips":["Run updates only when the system is stable (no concurrent AV scans, ample disk, steady power).","Keep the original installer/package-manager command handy for quick reinstall.","Backup or snapshot the binary before updating in critical environments."],"tags":["go","self-update","rename","rollback","recovery"],"backgroundTag":"self-update-inconsistent-state","analyzedSha":"724551b9ae87845594ef0408cff0e50eb6c90dc5","analyzedAt":"2026-08-28T07:32:55.105Z","schemaVersion":2},"datasetVersion":"2026-08-28T11:17:15.048Z"}