anomalyco/sst · error

failed to filter requirements: %w

Error message

failed to filter requirements: %w

What it means

Before installing Python dependencies for a zip build, SST rewrites requirements.txt into requirements-filtered.txt by stripping editable installs (-e / workspace paths) via filterEditableInstalls. This error is returned when that filtering step fails, wrapping the underlying read/write/parse error.

Source

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

	return nil
}

// copySyncedDependencies installs dependencies with correct platform targeting
func copySyncedDependencies(ctx context.Context, input *runtime.BuildInput, projectInfo *projectInfo, architecture string) error {
	requirementsPath := filepath.Join(input.Out(), "requirements.txt")

	if _, err := os.Stat(requirementsPath); os.IsNotExist(err) {
		slog.Warn("requirements.txt not found, skipping dependency installation", "path", requirementsPath)
		return nil
	}

	workspaceRoot := findWorkspaceRoot(projectInfo)

	// Filter editable installs from requirements
	filteredRequirementsPath := filepath.Join(input.Out(), "requirements-filtered.txt")
	err := filterEditableInstalls(requirementsPath, filteredRequirementsPath)
	if err != nil {
		return fmt.Errorf("failed to filter requirements: %w", err)
	}
	requirementsPath = filteredRequirementsPath

	// Cache key from requirements hash + architecture
	requirementsHash, err := hashFileContents(requirementsPath)
	var cacheKey string
	var depsCacheDir string

	if err == nil {
		cacheKey = fmt.Sprintf("%s-%s", requirementsHash, architecture)
		depsCacheDir = filepath.Join(filepath.Dir(input.Out()), ".deps", cacheKey)

		// Acquire lock to prevent concurrent installs for the same cache key
		globalDependencyInstallLocksMutex.Lock()
		cacheLock, exists := globalDependencyInstallLocks[cacheKey]
		if !exists {
			cacheLock = &sync.Mutex{}
			globalDependencyInstallLocks[cacheKey] = cacheLock

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Read the wrapped error; if it concerns requirements-filtered.txt existing as a directory, `rm -rf .sst` and redeploy.
  2. Validate requirements.txt is plain UTF-8 and uses standard syntax; simplify exotic editable lines (`-e ./pkg`).
  3. Let `uv export` regenerate requirements.txt rather than hand-editing it.
  4. Ensure the build output directory is writable by the deploying user.

Example fix

// before
# requirements.txt (hand edited, invalid)
-e file:///weird/path\xff
// after
$ rm -rf .sst
$ sst deploy  # let uv export regenerate requirements.txt
Defensive patterns

Strategy: validation

Validate before calling

const req = fs.readFileSync(path.join(buildOut, 'requirements.txt'), 'utf8');
if (!req.isWellFormed?.() && Buffer.from(req).includes(0xFF)) throw new Error('requirements.txt is not valid UTF-8; regenerate with uv export');

Type guard

null

Try / catch

try {
  await deploy();
} catch (e) {
  if (/failed to filter requirements/.test(e.message)) {
    fs.rmSync('.sst', { recursive: true, force: true }); // clears stale requirements-filtered.txt
    await deploy();
  } else throw e;
}

Prevention

When it happens

Trigger: filterEditableInstalls(requirementsPath, filteredRequirementsPath) fails when requirements.txt in input.Out() is unreadable, the output directory is unwritable, or the requirements file contains lines the filter cannot process (e.g. malformed UTF-8 or a very unusual editable syntax).

Common situations: requirements.txt hand-edited with non-UTF8 characters or exotic `-e` lines; previous interrupted build left a directory named requirements-filtered.txt in the output; read-only .sst output.

Related errors


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