anomalyco/sst · error

failed to move extracted package: %w

Error message

failed to move extracted package: %w

What it means

After extracting an sdist, the code renames/moves the extracted `name-version` directory to `name` via `moveExtractedPackage`. This error wraps any failure of that move — permission issues, cross-device rename, or target directory conflicts.

Source

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

	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)
	}

	baseName := dirName[:lastHyphen]
	extractedDir := filepath.Join(outputDir, dirName)
	targetDir := filepath.Join(outputDir, baseName)

	// Move extracted directory to target
	if err := moveExtractedPackage(extractedDir, targetDir, baseName); err != nil {
		return fmt.Errorf("failed to move extracted package: %w", err)
	}

	// Remove the original archive
	os.Remove(archiveFile)

	return nil
}

// extractZip extracts a zip archive (used for .whl files) to the destination directory.
func extractZip(archiveFile, destDir string) error {
	r, err := zip.OpenReader(archiveFile)
	if err != nil {
		return fmt.Errorf("failed to open zip: %w", err)
	}
	defer r.Close()

	for _, f := range r.File {
		// Guard against zip slip

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Clean the build output directory and rebuild (`rm -rf .sst/build`)
  2. Check that outputDir is on a local, writable filesystem
  3. Verify no conflicting directory named after the package base already exists in outputDir
  4. Re-run the deploy — transient locks from editors/AV scanners often clear

Example fix

// before: leftover requests/ dir from failed build causes move conflict
rm -rf .sst/build && sst deploy
Defensive patterns

Strategy: try-catch

Validate before calling

import { existsSync } from "fs";
if (existsSync(`${outputDir}/${baseName}`)) throw new Error(`Conflicting dir ${baseName} in output — clean build dir`);

Try / catch

try {
  await buildPackage(...);
} catch (e) {
  if (String(e).includes("failed to move extracted package")) {
    console.error("Clean .sst/build (conflicting dir or cross-device move) and redeploy:", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: `processPackageArchive` extracted successfully but `moveExtractedPackage(extractedDir, targetDir, baseName)` failed, e.g. because outputDir and the extracted dir are on different filesystems, or a previous partial build left a conflicting `targetDir` directory.

Common situations: Output dir on an overlay/NFS mount where rename across devices fails; leftover directories from an interrupted previous build; file locks (Windows or editors) holding the directory open.

Related errors


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