{"record":{"id":"d4a4231f534449f5","repo":"github/copilot-sdk","slug":"failed-to-hash-existing-output-w","errorCode":null,"errorMessage":"failed to hash existing output: %w","messagePattern":"failed to hash existing output: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":416,"sourceCode":"func buildBundle(info platformInfo, cliVersion, outputPath, goos string, includeLicense bool) (bundleArtifacts, error) {\n\toutputDir := filepath.Dir(outputPath)\n\tif outputDir == \"\" {\n\t\toutputDir = \".\"\n\t}\n\truntimeArtifactPath := filepath.Join(outputDir, runtimeLibArtifactName(cliVersion, info.runtimePlatform, goos))\n\twrapperArtifactPath := filepath.Join(outputDir, runtimeWrapperArtifactName(cliVersion, info.runtimePlatform, info.binaryName))\n\tassetsArtifactPath := filepath.Join(outputDir, runtimeAssetsArtifactName(cliVersion, info.runtimePlatform))\n\trequiredPaths := []string{outputPath, runtimeArtifactPath, wrapperArtifactPath, assetsArtifactPath}\n\tif includeLicense {\n\t\trequiredPaths = append(requiredPaths, licensePathForOutput(outputPath))\n\t}\n\n\tif filesExist(requiredPaths...) {\n\t\t// Idempotent output avoids re-downloading in CI or local rebuilds.\n\t\tfmt.Printf(\"Output runtime bundle for %s already exists, skipping download\\n\", info.runtimePlatform)\n\t\tbinaryHash, err := sha256FileFromCompressed(outputPath)\n\t\tif err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash existing output: %w\", err)\n\t\t}\n\t\truntimeHash, err := sha256FileFromCompressed(runtimeArtifactPath)\n\t\tif err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash existing runtime.node: %w\", err)\n\t\t}\n\t\twrapperHash, err := sha256FileFromCompressed(wrapperArtifactPath)\n\t\tif err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash existing runtime wrapper: %w\", err)\n\t\t}\n\t\tassetsHash, err := sha256File(assetsArtifactPath)\n\t\tif err != nil {\n\t\t\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash existing runtime assets: %w\", err)\n\t\t}\n\t\treturn bundleArtifacts{outputPath, binaryHash, runtimeArtifactPath, runtimeHash, wrapperArtifactPath, wrapperHash, assetsArtifactPath, assetsHash}, nil\n\t}\n\n\t// Create temp directory for download\n\ttempDir, err := os.MkdirTemp(\"\", \"copilot-bundler-*\")","sourceCodeStart":398,"sourceCodeEnd":434,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L398-L434","documentation":"When the bundle output already exists (idempotent-skip path), buildBundle hashes the existing binary with sha256FileFromCompressed to report/verify integrity. This error wraps any failure reading or hashing that existing output file — typically the file is missing, unreadable, or corrupted mid-write from a previous failed run.","triggerScenarios":"filesExist(requiredPaths...) returned true, but sha256FileFromCompressed(outputPath) fails — file deleted between the existence check and the hash, permission denied, or an I/O error reading the partially-written artifact.","commonSituations":"A previous bundler run was killed mid-download leaving a stale/locked file; output file removed by a concurrent clean job; read permissions changed; output on a flaky/network mount.","solutions":["Delete the stale output artifacts and rerun the bundler so it re-downloads fresh.","Check file permissions on the output path.","Verify no concurrent process deletes/moves files in the output directory.","Check disk health / mount stability if I/O errors persist.","Run the bundler with exclusive access to the output directory."],"exampleFix":"// before\nbinaryHash, err := sha256FileFromCompressed(outputPath)\nif err != nil {\n\treturn bundleArtifacts{}, fmt.Errorf(\"failed to hash existing output: %w\", err)\n}\n// after\nbinaryHash, err := sha256FileFromCompressed(outputPath)\nif err != nil {\n\tfmt.Printf(\"Existing output unreadable (%v), rebuilding\\n\", err)\n\t// fall through to full download path instead of failing\n}","handlingStrategy":"try-catch","validationCode":"if _, err := os.Open(outputPath); err != nil {\n\t// treat cache as invalid; force full rebuild\n}\nfi, _ := os.Stat(outputPath)\nif fi != nil && fi.Size() == 0 {\n\t// zero-length artifact from an interrupted run — rebuild\n}","typeGuard":null,"tryCatchPattern":"artifacts, err := buildBundle(...)\nif err != nil && strings.HasPrefix(err.Error(), \"failed to hash existing output\") {\n\tos.Remove(outputPath) // clear stale cache\n\tartifacts, err = buildBundle(...) // retry once\n}","preventionTips":["Run the bundler with exclusive access to the output directory.","Treat existence-check + hash as atomic; rebuild if hashing fails.","Clean stale artifacts after interrupted builds (trap signals in CI).","Avoid output dirs on unreliable network mounts."],"tags":["file-io","hashing","sha256","cache"],"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"}