anomalyco/sst · error

failed to create directory for %s: %w

Error message

failed to create directory for %s: %w

What it means

Raised in copyFile (pkg/runtime/python/python.go:395) when os.MkdirAll cannot create the destination's parent directory. copyFile is used by the lambda-bridge copy, workspace flattening, source copying, and dependency-package copies, so this error surfaces wherever SST stages Python files into artifact directories. Common causes: permissions, a file existing where a directory is needed, or read-only/invalid paths.

Source

Thrown at pkg/runtime/python/python.go:395

}

func (r *PythonRuntime) CreateBuildAsset(ctx context.Context, input *runtime.BuildInput) (*runtime.BuildOutput, error) {
	workingDir := path.ResolveRootDir(input.CfgPath)

	result, err := buildDeploy(ctx, input, filepath.Join(workingDir, ".sst/cache/deploy"), workingDir)
	if err != nil {
		slog.Error("build failed", "functionID", input.FunctionID, "error", err)
		return nil, err
	}

	slog.Info("function built", "functionID", input.FunctionID)
	return result, nil
}

// copyFile copies a single file from src to dst, creating parent directories as needed.
func copyFile(src, dst string) error {
	if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
		return fmt.Errorf("failed to create directory for %s: %w", dst, err)
	}

	srcFile, err := os.Open(src)
	if err != nil {
		return fmt.Errorf("failed to open source file: %w", err)
	}
	defer srcFile.Close()

	dstFile, err := os.Create(dst)
	if err != nil {
		return fmt.Errorf("failed to create destination file: %w", err)
	}
	defer dstFile.Close()

	if _, err := io.Copy(dstFile, srcFile); err != nil {
		return fmt.Errorf("failed to copy file contents: %w", err)
	}

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Read the wrapped cause; if permission denied run `sudo chown -R $(whoami) .sst` (and the platform dir if needed), then rerun
  2. If the error is 'not a directory'/'file exists', remove or rename the conflicting file at that path
  3. Verify disk space and that the destination isn't on a read-only mount; then restart the build

Example fix

// before
failed to create directory for .sst/artifacts/pkg/mod.py: mkdir .sst/artifacts/pkg: permission denied
// after
sudo chown -R $(whoami) .sst
sst deploy
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure destination parent path is not shadowed by a file
dir := filepath.Dir(dst)
if fi, err := os.Lstat(dir); err == nil && !fi.IsDir() {
    return fmt.Errorf("cannot create %s: exists as file", dir)
}
if err := os.MkdirAll(dir, 0755); err != nil { return err }

Try / catch

if err := copyFile(src, dst); err != nil {
    var pe *fs.PathError
    if errors.As(err, &pe) && (errors.Is(err, fs.ErrPermission) || errors.Is(err, fs.ErrExist)) {
        prepareDestDir(dst) // chown/remove shadowing file, then mkdir
        return copyFile(src, dst)
    }
    return err
}

Prevention

When it happens

Trigger: Artifact or target dir owned by root from container builds; a regular file exists at the directory path; read-only volume; path too long; disk full during Run's bridge copy or flattenWorkspaceLayouts.

Common situations: Root-owned .sst after Docker/CI builds; a repo file named like a package directory colliding during flattening; moving the project across filesystems with restrictive mounts.

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


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