{"record":{"id":"ffa595803daa64f8","repo":"github/copilot-sdk","slug":"existing-binary-hash-mismatch","errorCode":null,"errorMessage":"existing binary hash mismatch","messagePattern":"existing binary hash mismatch","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/internal/embeddedcli/embeddedcli.go","lineNumber":265,"sourceCode":"\n\t// Best effort to prevent concurrent installs.\n\tif release, _ := flock.Acquire(filepath.Join(installDir, \".copilot-cli.lock\")); release != nil {\n\t\tdefer release()\n\t}\n\n\tbinaryName := \"copilot\"\n\tif runtime.GOOS == \"windows\" {\n\t\tbinaryName += \".exe\"\n\t}\n\tfinalPath := filepath.Join(installDir, binaryName)\n\n\tif _, err := os.Stat(finalPath); err == nil {\n\t\texistingHash, err := hashFile(finalPath)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"hashing existing binary: %w\", err)\n\t\t}\n\t\tif !bytes.Equal(existingHash, config.CliHash) {\n\t\t\treturn \"\", fmt.Errorf(\"existing binary hash mismatch\")\n\t\t}\n\t\tif config.RuntimeExecutable != nil {\n\t\t\tpath, err := installRuntimePair(installDir)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\truntimePath = path\n\t\t}\n\t\tif config.RuntimeLib != nil {\n\t\t\tlibPath, err := installRuntimeLib(installDir)\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", err\n\t\t\t}\n\t\t\truntimeLibPath = libPath\n\t\t}\n\t\tif err := installRuntimeAssets(installDir); err != nil {\n\t\t\treturn \"\", err\n\t\t}","sourceCodeStart":247,"sourceCodeEnd":283,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/internal/embeddedcli/embeddedcli.go#L247-L283","documentation":"installAt in go/internal/embeddedcli/embeddedcli.go hashes the CLI binary already present at the target path and compares it to config.CliHash. If they differ, it refuses to overwrite the binary and returns this error. The library treats a foreign or different-version binary at the destination as something it must not clobber.","triggerScenarios":"Calling install (or installAt) when finalPath already exists and its SHA-256 hash does not equal config.CliHash — e.g. a stale build, a hand-placed binary, or an embedded config whose CliHash was regenerated after the on-disk binary was written.","commonSituations":"Upgrading the embedded CLI version without removing an older installed copy; another tool or user replaced the binary; a partially-patched binary; re-running install after modifying the embedded CLI bytes.","solutions":["Delete or rename the existing binary at finalPath and re-run install","Verify the file was not corrupted or replaced (re-hash it and compare against config.CliHash)","Rebuild/embed the matching CLI so config.CliHash matches the on-disk binary","If overwrite is intended, add logic to remove the stale binary before calling install"],"exampleFix":"// before\npath, err := embeddedcli.Install(ctx, cfg) // fails: existing binary hash mismatch\n// after\nif _, err := os.Stat(targetPath); err == nil {\n    os.Remove(targetPath) // remove stale/mismatched binary\n}\npath, err := embeddedcli.Install(ctx, cfg)","handlingStrategy":"try-catch","validationCode":"if _, err := os.Stat(targetPath); err == nil {\n    sum, _ := hashFile(targetPath)\n    if !bytes.Equal(sum, cfg.CliHash) {\n        os.Remove(targetPath) // or surface a friendly message\n    }\n}","typeGuard":"func binaryMatches(path string, want []byte) bool {\n    got, err := hashFile(path)\n    return err == nil && bytes.Equal(got, want)\n}","tryCatchPattern":"path, err := embeddedcli.Install(ctx, cfg)\nif err != nil {\n    if strings.Contains(err.Error(), \"existing binary hash mismatch\") {\n        os.Remove(targetPath)\n        path, err = embeddedcli.Install(ctx, cfg)\n    }\n    if err != nil { return err }\n}","preventionTips":["Remove stale binaries before version upgrades","Record installed version/hash in a manifest and compare before install","Never hand-edit or replace files inside the managed install directory"],"tags":["checksum","file-conflict","installation"],"backgroundTag":"checksum-mismatch","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}