anomalyco/sst · error

failed to create directory for %s: %v

Error message

failed to create directory for %s: %v

What it means

Raised in syncPythonFiles (pkg/runtime/python/python.go:337) when os.MkdirAll cannot create the parent directory of an artifact .py file before copying an updated/new source file. Indicates the artifact tree cannot be written: permissions, a file where a directory is expected, or a read-only mount.

Source

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

			}
		}
	}

	// 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 {
				return fmt.Errorf("failed to create directory for %s: %v", artifactPath, err)
			}

			if err := copyFile(sourcePath, artifactPath); err != nil {
				return fmt.Errorf("failed to copy %s to %s: %w", sourcePath, artifactPath, err)
			}
		}
	}

	return nil
}

// flattenSrcLayout removes the "src/pkg" segment from paths that follow the
// PEP 517 src-layout convention (e.g., "pkg/src/pkg/module" -> "pkg/module").
// Only flattens when the directory after "src" matches the directory before it.
func flattenSrcLayout(filePath string) string {
	parts := strings.Split(filePath, "/")
	if len(parts) < 3 {
		return filePath

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Check the wrapped error: if permission denied, `sudo chown -R $(whoami) .sst` and rerun; if 'file exists', remove/rename the conflicting file so the directory can be created
  2. Free disk space if the error is 'no space left on device'
  3. Rebuild artifacts from scratch: stop dev, `rm -rf` the function artifact dir, restart `sst dev`

Example fix

// before
failed to create directory for .sst/artifacts/api/src/api: mkdir: not a directory
// after
mv .sst/artifacts/api/src .sst/artifacts/api/src.bak  # file shadowing dir
sst dev
Defensive patterns

Strategy: validation

Validate before calling

// ensure no file shadows a needed directory and dest is writable
dir := filepath.Dir(artifactPath)
if fi, err := os.Lstat(dir); err == nil && !fi.IsDir() {
    return fmt.Errorf("%s is a file where a directory is required", dir)
}
if err := os.MkdirAll(dir, 0755); err != nil { return err }

Try / catch

if err := syncPythonFiles(src, dst); err != nil {
    if strings.Contains(err.Error(), "failed to create directory") {
        os.RemoveAll(dst) // rebuild artifacts cleanly after fixing perms/space
        return syncPythonFiles(src, dst)
    }
    return err
}

Prevention

When it happens

Trigger: Artifact dir read-only or owned by root (built in Docker); an existing regular file occupies the directory path being created (e.g. a file named like a package dir); disk full; ENAMETOOLONG for deeply nested workspace paths.

Common situations: Workspace-layout (package/src/package) Python projects where CI containers created root-owned artifacts; a repo file named `src` colliding with a needed directory; full disk on long dev sessions.

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/bc62fe83e94db433. Report an issue: GitHub.