anomalyco/sst · error

failed to extract wheel: %w

Error message

failed to extract wheel: %w

What it means

When a matched package archive is a `.whl` (zip) file, `processPackageArchive` extracts it via `extractZip`. This error wraps the failure of `zip.OpenReader` — the file could not be opened as a valid zip archive.

Source

Thrown at pkg/runtime/python/build.go:313

		return fmt.Errorf("no package archive found for %s (tried patterns: %s-*.whl, %s-*.tar.gz, %s-*.whl, %s-*.tar.gz)",
			pkg.Name, normalizedName, normalizedName, pkg.Name, pkg.Name)
	}

	// Process each archive file
	for _, archiveFile := range files {
		if err := processPackageArchive(archiveFile, outputDir); err != nil {
			return fmt.Errorf("failed to process archive %s: %w", archiveFile, err)
		}
	}

	return nil
}

// processPackageArchive extracts and cleans up a single package archive
func processPackageArchive(archiveFile, outputDir string) error {
	if strings.HasSuffix(archiveFile, ".whl") {
		if err := extractZip(archiveFile, outputDir); err != nil {
			return fmt.Errorf("failed to extract wheel: %w", err)
		}

		os.Remove(archiveFile)

		return nil
	}

	// Extract tar.gz
	if err := extractTarGz(archiveFile, outputDir); err != nil {
		return fmt.Errorf("failed to extract archive: %w", err)
	}

	// Get the directory name without version number
	archiveBaseName := filepath.Base(archiveFile)
	dirName := strings.TrimSuffix(archiveBaseName, ".tar.gz")
	lastHyphen := strings.LastIndex(dirName, "-")
	if lastHyphen == -1 {
		return fmt.Errorf("invalid archive name format: %s", archiveBaseName)

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Remove the offending .whl from the build output and rebuild so pip re-downloads it
  2. Verify the wheel is valid: `python -m zipfile -t <file>.whl`
  3. Check network/proxy settings if downloads were corrupted
  4. Clean the whole build directory (`rm -rf .sst/build`) to avoid mixing stale artifacts

Example fix

// before: stale 0-byte requests-2.31.0-py3-none-any.whl in build dir
// after
cd .sst/build && rm -f *.whl && cd ../.. && sst deploy
Defensive patterns

Strategy: validation

Validate before calling

import { statSync } from "fs";
const whl = statSync(archivePath);
if (whl.size < 1024) throw new Error(`${archivePath} too small to be a valid wheel`);

Try / catch

try {
  await buildPackage(...);
} catch (e) {
  if (String(e).includes("failed to extract wheel")) {
    console.error("Invalid wheel — delete it and rebuild:", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Glob matched a `*.whl` file that is not a valid zip: truncated download, an HTML error page saved as .whl, or zero-byte file.

Common situations: Corporate proxy returning error pages that pip saved as wheels; disk-full during download; manually placed files ending in .whl in the build dir; interrupted previous build.

Related errors


AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30). Data as JSON: /api/errors/ccaf42b536e3d023. Report an issue: GitHub.