github/copilot-sdk · error

file not found in tarball

Error message

file %q not found in tarball

What it means

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.

Solutions

  1. List the archive contents (tar -tzf <file>.tgz) and correct targetPath to the actual member name
  2. Verify the downloaded tarball is the expected package/version — re-download if the upstream layout changed
  3. If the file is legitimately optional, switch the call site to extractOptionalFileFromTarball, which returns (false, nil) on absence
  4. Add a debug log of every tar entry name visited to compare against targetPath

Example fix

// before
err := extractFileFromTarball(tgzPath, "copilot", destDir)
// after
found, err := extractOptionalFileFromTarball(tgzPath, "copilot", destDir)
if err != nil {
	return err
}
if !found {
	return fmt.Errorf("file %q not found in tarball; contents: %v", "copilot", listTarEntries(tgzPath))
}
Defensive patterns

Strategy: fallback

Validate before calling

// verify the target path exists in the tarball first
out, _ := exec.Command("tar", "-tzf", tgzPath).Output()
if !strings.Contains(string(out), targetPath) { /* adjust targetPath */ }

Try / catch

// Go
found, err := extractOptionalFileFromTarball(tgzPath, target, destDir)
if err != nil { return err }
if !found { /* handle absence: fallback path or clear message */ }

Prevention

When it happens

Trigger: 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.

Common situations: 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).

Understand the failure class

Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.

Related errors


AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09). Data as JSON: /api/errors/453cf65ddf001215. Report an issue: GitHub.

Appendix: source

Thrown at go/cmd/bundler/main.go:1194

			outFile, err := os.OpenFile(outPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, os.FileMode(header.Mode))
			if err != nil {
				return fmt.Errorf("failed to create output file: %w", err)
			}

			if _, err := io.Copy(outFile, tarReader); err != nil {
				if cerr := outFile.Close(); cerr != nil {
					return fmt.Errorf("failed to extract binary (copy error: %v, close error: %v)", err, cerr)
				}
				return fmt.Errorf("failed to extract binary: %w", err)
			}
			if err := outFile.Close(); err != nil {
				return fmt.Errorf("failed to close output file: %w", err)
			}
			return nil
		}
	}

	return fmt.Errorf("file %q not found in tarball", targetPath)
}

// extractOptionalFileFromTarball extracts a single file from a .tgz into destDir
// like extractFileFromTarball, but returns (false, nil) instead of an error when
// the file is absent. Used for the runtime library, which older CLI packages do
// not ship.
func extractOptionalFileFromTarball(tarballPath, destDir, targetPath, outputName string) (bool, error) {
	err := extractFileFromTarball(tarballPath, destDir, targetPath, outputName)
	if err == nil {
		return true, nil
	}
	if strings.Contains(err.Error(), "not found in tarball") {
		return false, nil
	}
	return false, err
}

// compressZstdFile compresses src into dst using zstd.

View on GitHub (pinned to cd8cf15dc3)