{"record":{"id":"cc17976f42c422e0","repo":"github/copilot-sdk","slug":"failed-to-hash-output-binary-w","errorCode":null,"errorMessage":"failed to hash output binary: %w","messagePattern":"failed to hash output binary: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":458,"sourceCode":"\tbinaryPath, tarballPath, err := downloadCLIBinary(info.runtimePlatform, info.binaryName, cliVersion, tempDir)\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to download CLI binary: %w\", err)\n\t}\n\n\tif outputDir != \".\" {\n\t\tif err := os.MkdirAll(outputDir, 0755); err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to create output directory: %w\", err)\n\t\t}\n\t}\n\tif includeLicense {\n\t\tif err := extractCLILicense(tarballPath, outputPath); err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to extract CLI license: %w\", err)\n\t\t}\n\t}\n\n\tbinaryHash, err := sha256File(binaryPath)\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash output binary: %w\", err)\n\t}\n\tif err := compressZstdFile(binaryPath, outputPath); err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to write output binary: %w\", err)\n\t}\n\n\trawLibPath := filepath.Join(tempDir, \"runtime.node\")\n\tif err := extractFileFromTarball(\n\t\ttarballPath,\n\t\ttempDir,\n\t\t\"package/prebuilds/\"+info.runtimePlatform+\"/runtime.node\",\n\t\t\"runtime.node\",\n\t); err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"runtime package is missing prebuilds/%s/runtime.node: %w\", info.runtimePlatform, err)\n\t}\n\truntimeHash, err := sha256File(rawLibPath)\n\tif err != nil {\n\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash runtime.node: %w\", err)\n\t}","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L440-L476","documentation":"After the CLI binary has been extracted, buildBundle computes its SHA-256 digest with sha256File to record in the bundle manifest. If hashing fails — typically because binaryPath cannot be opened or read — the error is wrapped with this message and bundling stops.","triggerScenarios":"sha256File(binaryPath) fails: the extracted binary file does not exist, was deleted between steps, or cannot be read due to permissions; also on any underlying I/O error.","commonSituations":"Antivirus/EDR quarantining the freshly extracted native binary so the hash step finds it gone, a disk-full or I/O error while reading a large binary, or a temp directory cleaner removing files mid-build.","solutions":["Verify the binary exists at the temp path and is readable (ls -l); re-run the bundle.","Exclude the bundler temp/output directories from antivirus real-time scanning if the binary is being quarantined.","Check disk space and filesystem health (dmesg for I/O errors) if reads fail intermittently.","Use a stable temp directory (set TMPDIR) that background cleaners will not purge during the build."],"exampleFix":"// before\n# AV quarantines extracted binary during build\n\n// after\n# exclude temp dir from AV, then set a fixed TMPDIR\necho \"/tmp/bundler-*\" >> /etc/clamav/on-access-exclude.conf\nTMPDIR=/tmp/bundler-work bundler ...","handlingStrategy":"validation","validationCode":"info, err := os.Stat(binaryPath)\nif err != nil {\n\treturn fmt.Errorf(\"binary missing at %s: %w\", binaryPath, err)\n}\nif info.Size() == 0 {\n\treturn fmt.Errorf(\"binary at %s is empty; extraction likely failed\", binaryPath)\n}","typeGuard":"func fileReadable(path string) bool {\n\tf, err := os.Open(path)\n\tif err != nil {\n\t\treturn false\n\t}\n\tf.Close()\n\treturn true\n}","tryCatchPattern":"if err := buildBundle(...); err != nil {\n\tif strings.Contains(err.Error(), \"failed to hash output binary\") {\n\t\tvar pe *fs.PathError\n\t\tif errors.As(err, &pe) {\n\t\t\tlog.Errorf(\"binary %s unreadable; check AV quarantine and disk health\", pe.Path)\n\t\t}\n\t}\n\treturn err\n}","preventionTips":["Allowlist bundler temp/output paths in antivirus/EDR real-time scanning.","Use a dedicated TMPDIR that scheduled cleaners do not purge.","Monitor free disk space before large bundle builds.","Keep extraction and hashing in the same build step so nothing is removed in between."],"tags":["hash","sha256","filesystem","cli"],"backgroundTag":"file-read-failed","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}