anomalyco/sst · error
failed to copy directory %s: %w
Error message
failed to copy directory %s: %w
What it means
copySourceFilesSimple locates the top-level source directory of the handler (e.g. `services/api/functions/handler.ts` → first path component that exists as a dir in the workspace) and recursively copies it into the build output. This error is returned when that copyDir fails. It wraps the underlying OS error from copying a file inside that directory.
Source
Thrown at pkg/runtime/python/build.go:768
}
outputBase := input.Out()
// For container builds, source files go at root of build context (Dockerfile expects it).
// For zip builds, preserve the nested directory structure via outputPrefix.
if outputPrefix != "" && !input.IsContainer {
outputBase = filepath.Join(input.Out(), outputPrefix)
}
if strings.Contains(handlerPath, "/") {
// Find the top-level directory that exists in the workspace
parts := strings.Split(handlerPath, "/")
copied := false
for i := 0; i < len(parts)-1; i++ {
candidate := parts[i]
candidatePath := filepath.Join(workspaceDir, candidate)
if info, err := os.Stat(candidatePath); err == nil && info.IsDir() {
if err := copyDir(candidatePath, filepath.Join(outputBase, candidate), skipContent); err != nil {
return fmt.Errorf("failed to copy directory %s: %w", candidate, err)
}
copied = true
break
}
}
if !copied {
// Handler path fully resolved by workspaceDir — root .py files will be copied below
}
}
// Also copy root-level .py files
entries, err := os.ReadDir(workspaceDir)
if err != nil {
return fmt.Errorf("failed to read workspace directory: %w", err)
}
for _, entry := range entries {
if !entry.IsDir() && strings.HasSuffix(entry.Name(), ".py") {
if err := copyFile(filepath.Join(workspaceDir, entry.Name()), filepath.Join(outputBase, entry.Name())); err != nil {View on GitHub (pinned to a0bd20f762)
Solutions
- Check the wrapped error for the failing filename; restore permissions (`chmod -R u+r <dir>`) or recreate the missing file.
- Stop concurrent watchers/generators, then rerun the deploy.
- Clean the build output (`rm -rf .sst`) and redeploy to clear conflicting destinations.
- Verify free disk space on the volume holding the build output.
Example fix
// before Error: failed to copy source files: failed to copy directory functions: open functions/handler.py: permission denied // after $ chmod -R u+r functions/ $ sst deploy
Defensive patterns
Strategy: try-catch
Validate before calling
fs.accessSync(handlerDir, fs.constants.R_OK); fs.accessSync(buildOut, fs.constants.W_OK);
Type guard
null
Try / catch
try {
await deploy();
} catch (e) {
if (/failed to copy directory/.test(e.message)) {
const m = e.message.match(/failed to copy directory (\S+): (.*)/);
console.error(`Fix perms/missing file in ${m?.[1]}: ${m?.[2]}`);
throw e;
} else throw e;
} Prevention
- chmod -R u+r source dirs before CI deploys
- Pause file watchers/generators during deploy
- Clean .sst when build output layout changes
- Keep source tree free of unreadable or root-owned files
When it happens
Trigger: copyDir(candidatePath, filepath.Join(outputBase, candidate), skipContent) fails in copySourceFilesSimple — a source file disappears mid-copy, a file is unreadable (permissions), or the destination cannot be written.
Common situations: Handler source directory contains files owned by another user; a file is removed by a code generator/watcher during deploy; read-only source mount; output directory full.
Related errors
- failed to copy %s to %s: %w
- failed to copy file %s: %w
- failed to move extracted package: %w
- failed to create output directory: %w
- failed to copy source files: %w
AI-assisted analysis of anomalyco/sst@a0bd20f762 (2026-08-30).
Data as JSON: /api/errors/0bcbfdf62d8180a9.
Report an issue: GitHub.