{"record":{"id":"16b525050f416903","repo":"can1357/oh-my-pi","slug":"formatverificationfailure-verification-expected","errorCode":null,"errorMessage":"${formatVerificationFailure(verification, expectedVersion)}; restored previous ${APP_NAME} launcher","messagePattern":"(.+?); restored previous (.+?) launcher","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/cli/update-cli.ts","lineNumber":1882,"sourceCode":"\n\t\t// Verify the exe by its explicit path: $which cached the shim path when\n\t\t// the update target was resolved, and the shim was just renamed away, so\n\t\t// a PATH re-resolution here would test a file that no longer exists.\n\t\tconst verify = options.verifyBinary ?? verifyBinaryAtPath;\n\t\tconst verification = await verify(exePath, expectedVersion);\n\t\tif (!verification.ok) {\n\t\t\tfor (const { launcher, backup } of retired) {\n\t\t\t\ttry {\n\t\t\t\t\tawait fs.promises.rename(backup, launcher);\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t\tfor (const { launcher, original } of forwarded) {\n\t\t\t\ttry {\n\t\t\t\t\tawait Bun.write(launcher, original);\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t\tawait unlinkIfExists(exePath);\n\t\t\tthrow new Error(\n\t\t\t\t`${formatVerificationFailure(verification, expectedVersion)}; restored previous ${APP_NAME} launcher`,\n\t\t\t);\n\t\t}\n\t\tfor (const { backup } of retired) {\n\t\t\tawait removeBackupBestEffort(backup);\n\t\t}\n\t\t// Reclaim exe backups and retired-shim leftovers from earlier attempts.\n\t\tfor (const ext of [\".exe\", \"\", \".cmd\", \".ps1\", \".bat\"]) {\n\t\t\tawait sweepStaleUpdateArtifacts(path.join(launcherDir, `${APP_NAME}${ext}`));\n\t\t}\n\t});\n\tfor (const { launcher } of forwarded) {\n\t\tconsole.log(chalk.dim(`Converted ${launcher} to a forwarder (it could not be removed).`));\n\t}\n\tfor (const launcher of stuck) {\n\t\tconsole.log(\n\t\t\tchalk.yellow(\n\t\t\t\t`Could not retire ${launcher}; shells that prefer it may keep launching the old version until it is deleted manually.`,","sourceCodeStart":1864,"sourceCodeEnd":1900,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/cli/update-cli.ts#L1864-L1900","documentation":"Thrown during the binary/launcher self-update path when the newly installed launcher fails version verification and the updater rolls back: previously replaced launchers are restored from backup, the new executable is unlinked, and this error reports the verification failure plus the rollback. The install is left in its pre-update state.","triggerScenarios":"Standalone binary update flow: launcher files were rewritten, post-install verification (run launcher, check version) fails — e.g. downloaded binary is for the wrong platform/arch, corrupted download, or the launcher shim points at the wrong executable — triggering the restore-backup + unlink branch.","commonSituations":"Partial/interrupted download; platform mismatch (arm64 vs x64 binary); enterprise antivirus quarantining the new binary; version mismatch because the release channel returned an unexpected version.","solutions":["Read formatVerificationFailure output — it states expected vs actual version","Re-run the update; a transient download truncation is the most common cause","Verify you downloaded the binary matching your platform/arch","Check antivirus/quarantine logs if the binary disappears or won't execute","Download and run the official standalone installer manually, then retry update"],"exampleFix":"// retry with a clean download if verification failed\ntry {\n\tawait updateSelf({ force: true });\n} catch (err) {\n\tconsole.error(err.message); // \"...; restored previous launcher\" => rollback happened\n\tconsole.error(\"previous install intact; retry or use standalone installer\");\n}","handlingStrategy":"retry","validationCode":"// pre-flight: confirm downloaded binary runs and reports the right version\nconst v = await $`${downloadedBinary} --version`.nothrow();\nif (v.exitCode !== 0 || v.text().trim() !== expectedVersion) throw new Error(\"binary pre-flight failed\");","typeGuard":"function isExpectedVersion(output: string, expected: string): boolean {\n\treturn output.trim() === expected;\n}","tryCatchPattern":"try {\n\tawait updateSelf({ binary: true });\n} catch (err) {\n\tif (err.message.includes(\"restored previous\")) {\n\t\t// rollback happened; previous install intact — retry or use standalone installer\n\t\tconsole.warn(\"update rolled back:\", err.message);\n\t} else throw err;\n}","preventionTips":["Use stable network paths for binary downloads; avoid flaky proxies","Confirm platform/arch matches the release asset before install","Exclude the install directory from antivirus real-time scanning"],"tags":["self-update","verification","rollback","binary"],"backgroundTag":"update-verification-failed","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}