anomalyco/sst · error
failed to open archive: %w
Error message
failed to open archive: %w
What it means
extractTarGz wraps any failure from os.Open(archiveFile) with the message "failed to open archive". It fires when the downloaded/located .tar.gz package file cannot be opened for reading — the file is missing, the path is wrong, or the process lacks read permission. The original OS error is preserved via %w so callers can inspect it with errors.Is/As.
Source
Thrown at pkg/runtime/python/build.go:401
return err
}
if _, err := io.Copy(out, rc); err != nil {
out.Close()
rc.Close()
return err
}
out.Close()
rc.Close()
}
return nil
}
// extractTarGz extracts a .tar.gz archive to the destination directory.
func extractTarGz(archiveFile, destDir string) error {
f, err := os.Open(archiveFile)
if err != nil {
return fmt.Errorf("failed to open archive: %w", err)
}
defer f.Close()
gz, err := gzip.NewReader(f)
if err != nil {
return fmt.Errorf("failed to create gzip reader: %w", err)
}
defer gz.Close()
tr := tar.NewReader(gz)
for {
hdr, err := tr.Next()
if err == io.EOF {
break
}
if err != nil {
return fmt.Errorf("failed to read tar entry: %w", err)
}View on GitHub (pinned to a0bd20f762)
Solutions
- Verify the archive file exists at the expected path (ls/stat the path from the error context) before re-running the build
- Re-run the package download step (pip download / uv pip) so the .tar.gz is recreated
- Check file permissions and that the build process user can read the archive
- Clear stale build caches and rebuild so the archive is re-fetched
- Check disk space and mount health if the file lives on a volume
Example fix
// before: extracting a possibly-missing archive
extractTarGz(archiveFile, destDir)
// after: check existence first
if _, err := os.Stat(archiveFile); err != nil {
return fmt.Errorf("archive missing, re-download package: %w", err)
}
if err := extractTarGz(archiveFile, destDir); err != nil {
return err
} Defensive patterns
Strategy: validation
Validate before calling
if _, err := os.Stat(archiveFile); err != nil {
return fmt.Errorf("archive %s not available: %w", archiveFile, err)
}
if info, _ := os.Stat(archiveFile); info.Size() == 0 {
return fmt.Errorf("archive %s is empty", archiveFile)
} Try / catch
if err := extractTarGz(archiveFile, destDir); err != nil {
var pathErr *os.PathError
if errors.As(err, &pathErr) && errors.Is(pathErr.Err, os.ErrNotExist) {
// re-download the archive and retry
}
return err
} Prevention
- Stat the archive before extraction
- Re-download on every build when integrity is in doubt instead of trusting caches
- Run builds as a user with read access to the cache directory
- Fail fast after download by checking file size > 0
When it happens
Trigger: processPackageArchive calls extractTarGz with an archiveFile path that does not exist, was deleted between download and extraction, or cannot be opened due to permissions (os.Open returns an error such as ENOENT, EACCES, or EISDIR).
Common situations: A pip-download step failed silently leaving no wheel/sdist on disk; the archive path was built with a wrong hash or version directory; a temp directory was cleaned up prematurely; a Docker/CI cache references a file that no longer exists; the file is read-only for the build user.
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
- failed to remove old directory: %w
- failed to move src directory contents: %w
- failed to rename directory: %w
- failed to create output directory: %w
- failed to copy %s to %s: %w
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/1ef7b2b45389233b.
Report an issue: GitHub.