github/copilot-sdk · error
binary not found after extraction
Error message
binary not found after extraction: %w
What it means
Immediately after extraction, the bundler stats the expected binary path to confirm the wrapper entrypoint actually landed in destDir. If os.Stat fails, the file is missing (or unreadable) despite extraction reporting success, and this error wraps the stat error. It's a post-extraction sanity check.
Solutions
- Check antivirus/EDR logs for quarantine of the extracted binary and add an exclusion.
- Ensure no concurrent process cleans or mutates destDir during buildBundle.
- Verify binaryName/path construction matches what extractFileFromTarball writes.
- Re-run the build; a transient filesystem race usually won't recur.
Example fix
// before: shared mutable destDir across parallel builds
// after: unique per-build destination
destDir = filepath.Join(baseDir, fmt.Sprintf("build-%d", os.Getpid())) Defensive patterns
Strategy: try-catch
Validate before calling
// ensure destDir is writable and not subject to external cleanup
if err := os.MkdirAll(destDir, 0o755); err != nil { return err }
if f, err := os.CreateTemp(destDir, ".probe"); err != nil { return err } else { f.Close(); os.Remove(f.Name()) } Try / catch
if err := buildBundle(...); err != nil {
if strings.Contains(err.Error(), "binary not found after extraction") {
checkAVQuarantineLog(); retryInIsolatedDir()
}
} Prevention
- Add AV/EDR exclusions for your build output directories.
- Use per-process/per-build destination directories to avoid races.
- Never share one destDir across concurrent buildBundle runs.
- Re-check that binaryName construction matches extraction targets.
When it happens
Trigger: os.Stat(binaryPath) returns non-nil right after extractFileFromTarball succeeded — the binary was written to an unexpected path, deleted, or destDir was modified between extraction and stat.
Common situations: Antivirus/EDR quarantining freshly extracted executables; concurrent builds sharing destDir and clobbering files; extraction writing under a slightly different name; permissions on destDir changed mid-build.
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
- CreateSessionFSProvider is required in session config when…
- SessionFS capabilities declare SQLite support but the…
- failed to read package directory
- failed to evaluate build constraints in
- failed to create tarball file
AI-assisted analysis of github/copilot-sdk@cd8cf15dc3 (2026-09-09).
Data as JSON: /api/errors/002f3abf15fd98a1.
Report an issue: GitHub.
Appendix: source
Thrown at go/cmd/bundler/main.go:1054
// The SDK release package intentionally omits the legacy SEA binary. Preserve
// embeddedcli.Path compatibility by installing the runtime wrapper under the
// historical copilot[.exe] name; the normal client path uses the adjacent
// wrapper/runtime.node pair directly.
binaryPath := filepath.Join(destDir, binaryName)
wrapperName := runtimeWrapperName(binaryName)
if err := extractFileFromTarball(
tarballPath,
destDir,
"package/prebuilds/"+runtimePlatform+"/"+wrapperName,
binaryName,
); err != nil {
return "", "", fmt.Errorf("failed to extract runtime wrapper compatibility entrypoint: %w", err)
}
// Verify binary exists
if _, err := os.Stat(binaryPath); err != nil {
return "", "", fmt.Errorf("binary not found after extraction: %w", err)
}
// Make executable on Unix
if !strings.HasSuffix(binaryName, ".exe") {
if err := os.Chmod(binaryPath, 0755); err != nil {
return "", "", fmt.Errorf("failed to chmod binary: %w", err)
}
}
stat, err := os.Stat(binaryPath)
if err != nil {
return "", "", fmt.Errorf("failed to stat binary: %w", err)
}
sizeMB := float64(stat.Size()) / 1024 / 1024
fmt.Printf("Downloaded %s (%.1f MB)\n", binaryName, sizeMB)
return binaryPath, tarballPath, nil
}View on GitHub (pinned to cd8cf15dc3)