anomalyco/sst · error
failed to delete %s: %v
Error message
failed to delete %s: %v
What it means
Raised in syncPythonFiles (pkg/runtime/python/python.go:318) when os.Remove cannot delete a stale .py file that exists in the artifact directory but no longer in the source tree (for legacy workspace layouts). Typical causes: read-only artifact files/dirs, the file having been recreated as a directory, or permission mismatch.
Source
Thrown at pkg/runtime/python/python.go:318
}
if !info.IsDir() && strings.HasSuffix(path, ".py") {
artifactFiles[relPath] = info
}
return nil
})
if err != nil {
return fmt.Errorf("failed to scan artifact files: %v", err)
}
}
// Delete files in artifacts that no longer exist in source
for relPath := range artifactFiles {
if _, exists := sourceFiles[relPath]; !exists {
artifactPath := filepath.Join(destDir, relPath)
if err := os.Remove(artifactPath); err != nil {
return fmt.Errorf("failed to delete %s: %v", artifactPath, err)
}
}
}
// Copy/update changed files
for relPath, sourceInfo := range sourceFiles {
sourcePath := filepath.Join(srcDir, relPath)
artifactPath := filepath.Join(destDir, relPath)
needsCopy := true
if artifactInfo, exists := artifactFiles[relPath]; exists {
if !sourceInfo.ModTime().After(artifactInfo.ModTime()) {
needsCopy = false
}
}
if needsCopy {
if err := os.MkdirAll(filepath.Dir(artifactPath), 0755); err != nil {View on GitHub (pinned to a0bd20f762)
Solutions
- Read the failing artifactPath in the message and `rm -f` it manually with sufficient privileges (or chown the artifact dir to your user)
- If it became a directory, remove it with `rm -rf`; restart `sst dev` so sync reruns
- If artifacts are root-owned from container builds, run `sudo chown -R $(whoami) .sst` or build as the same user
Example fix
// before failed to delete .sst/artifacts/old_module.py: permission denied // after sudo rm -f .sst/artifacts/old_module.py sst dev
Defensive patterns
Strategy: try-catch
Validate before calling
// pre-check stale artifact file is removable
artifactPath := filepath.Join(destDir, relPath)
if _, err := os.Lstat(artifactPath); err == nil {
if err := os.Chmod(artifactPath, 0644); err != nil { /* surface unwritable artifact early */ }
} Try / catch
if err := syncPythonFiles(src, dst); err != nil {
var pe *fs.PathError
if strings.Contains(err.Error(), "failed to delete") && errors.As(err, &pe) {
os.RemoveAll(pe.Path) // force-remove with elevated/user perms
return syncPythonFiles(src, dst)
}
return err
} Prevention
- After container-built artifacts, chown .sst to your user before dev
- Rename source modules via git mv and restart dev rather than editing artifacts in place
- Keep artifact dirs writable (0755 dirs, 0644 files)
- Never mount .sst read-only for dev workflows
When it happens
Trigger: Source .py file renamed/deleted while the artifact copy is read-only or owned by another user; artifact path now a non-empty directory; artifact filesystem mounted read-only.
Common situations: Renaming a module in a workspace-layout Python project while artifacts were built by a container/CI as root; NFS/bind-mounted artifact dirs with root-squash; git checkout leaving stale artifacts with different permissions.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- failed to scan source files: %v
- failed to scan artifact files: %v
- failed to create directory for %s: %v
- failed to remove old directory: %w
- failed to walk extracted directory: %w
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/e863faea70629bd2.
Report an issue: GitHub.