{"record":{"id":"453cf65ddf001215","repo":"github/copilot-sdk","slug":"file-q-not-found-in-tarball","errorCode":null,"errorMessage":"file %q not found in tarball","messagePattern":"file %q not found in tarball","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/cmd/bundler/main.go","lineNumber":1194,"sourceCode":"\t\t\toutFile, err := os.OpenFile(outPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(header.Mode))\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create output file: %w\", err)\n\t\t\t}\n\n\t\t\tif _, err := io.Copy(outFile, tarReader); err != nil {\n\t\t\t\tif cerr := outFile.Close(); cerr != nil {\n\t\t\t\t\treturn fmt.Errorf(\"failed to extract binary (copy error: %v, close error: %v)\", err, cerr)\n\t\t\t\t}\n\t\t\t\treturn fmt.Errorf(\"failed to extract binary: %w\", err)\n\t\t\t}\n\t\t\tif err := outFile.Close(); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to close output file: %w\", err)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t}\n\n\treturn fmt.Errorf(\"file %q not found in tarball\", targetPath)\n}\n\n// extractOptionalFileFromTarball extracts a single file from a .tgz into destDir\n// like extractFileFromTarball, but returns (false, nil) instead of an error when\n// the file is absent. Used for the runtime library, which older CLI packages do\n// not ship.\nfunc extractOptionalFileFromTarball(tarballPath, destDir, targetPath, outputName string) (bool, error) {\n\terr := extractFileFromTarball(tarballPath, destDir, targetPath, outputName)\n\tif err == nil {\n\t\treturn true, nil\n\t}\n\tif strings.Contains(err.Error(), \"not found in tarball\") {\n\t\treturn false, nil\n\t}\n\treturn false, err\n}\n\n// compressZstdFile compresses src into dst using zstd.","sourceCodeStart":1176,"sourceCodeEnd":1212,"githubUrl":"https://github.com/github/copilot-sdk/blob/cd8cf15dc3f9e762615790aaed0a771a0f392755/go/cmd/bundler/main.go#L1176-L1212","documentation":"When iterating the tarball's entries, no archive member matches the requested targetPath, so extractFileFromTarball reports the file as absent with this error. The function scans the entire archive (including nested tar layers) and only fails with this message once every entry has been checked without a match.","triggerScenarios":"Calling extractFileFromTarball (directly or via buildBundle / downloadCLIBinary) with a targetPath that does not exist inside the downloaded .tgz — wrong filename, wrong internal directory prefix, or a package layout that changed between CLI versions.","commonSituations":"Upstream CLI release renames or relocates the binary inside the archive; hard-coded target path like 'copilot' vs 'bin/copilot'; downloading a package variant that legitimately lacks the file (for the optional runtime library, use extractOptionalFileFromTarball instead).","solutions":["List the archive contents (tar -tzf <file>.tgz) and correct targetPath to the actual member name","Verify the downloaded tarball is the expected package/version — re-download if the upstream layout changed","If the file is legitimately optional, switch the call site to extractOptionalFileFromTarball, which returns (false, nil) on absence","Add a debug log of every tar entry name visited to compare against targetPath"],"exampleFix":"// before\nerr := extractFileFromTarball(tgzPath, \"copilot\", destDir)\n// after\nfound, err := extractOptionalFileFromTarball(tgzPath, \"copilot\", destDir)\nif err != nil {\n\treturn err\n}\nif !found {\n\treturn fmt.Errorf(\"file %q not found in tarball; contents: %v\", \"copilot\", listTarEntries(tgzPath))\n}","handlingStrategy":"fallback","validationCode":"// verify the target path exists in the tarball first\nout, _ := exec.Command(\"tar\", \"-tzf\", tgzPath).Output()\nif !strings.Contains(string(out), targetPath) { /* adjust targetPath */ }","typeGuard":null,"tryCatchPattern":"// Go\nfound, err := extractOptionalFileFromTarball(tgzPath, target, destDir)\nif err != nil { return err }\nif !found { /* handle absence: fallback path or clear message */ }","preventionTips":["Pin and verify upstream CLI package versions","List archive contents when upgrading the CLI package","Use extractOptionalFileFromTarball for files known to be optional"],"tags":["tarball","file-not-found","packaging"],"backgroundTag":"file-not-found","analyzedSha":"cd8cf15dc3f9e762615790aaed0a771a0f392755","analyzedAt":"2026-09-09T18:32:31.973Z","contentChangedAt":"2026-09-09T18:32:31.973Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}