anomalyco/sst · error

failed to create directory for workspace package %s: %w

Error message

failed to create directory for workspace package %s: %w

What it means

During a container build, SST creates the destination directory tree for each relative-path workspace package from requirements.txt via os.MkdirAll before copying files. This error is returned when that MkdirAll fails. It wraps the OS error, typically permissions or an invalid path component (e.g. a file exists where a directory is expected).

Source

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

			// Already exists — just ensure pyproject.toml is present for uv pip install
			srcPyproject := filepath.Join(fullPath, "pyproject.toml")
			destPyproject := filepath.Join(destPath, "pyproject.toml")
			if _, err := os.Stat(srcPyproject); err == nil {
				if _, err := os.Stat(destPyproject); err != nil {
					data, readErr := os.ReadFile(srcPyproject)
					if readErr != nil {
						return fmt.Errorf("failed to read pyproject.toml for workspace package %s: %w", pkgPath, readErr)
					}
					if err := os.WriteFile(destPyproject, data, 0644); err != nil {
						return fmt.Errorf("failed to copy pyproject.toml for workspace package %s: %w", pkgPath, err)
					}
				}
			}
			continue
		}

		if err := os.MkdirAll(filepath.Dir(destPath), 0755); err != nil {
			return fmt.Errorf("failed to create directory for workspace package %s: %w", pkgPath, err)
		}

		// Preserve pyproject.toml and metadata for uv pip install
		if err := copyDir(fullPath, destPath, skipBuildArtifacts); err != nil {
			return fmt.Errorf("failed to copy workspace package %s: %w", pkgPath, err)
		}

	}

	return nil
}

// copySourceFilesSimple copies handler source files to the build output.
// Workspace packages are installed via uv pip install separately.
func copySourceFilesSimple(input *runtime.BuildInput, projectInfo *projectInfo) error {
	workspaceDir := projectInfo.SourceRoot
	if projectInfo.PyprojectPath != "" {
		workspaceDir = filepath.Dir(projectInfo.PyprojectPath)

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Delete the stale build output (`rm -rf .sst` or the relevant .sst/platform output dir) and redeploy.
  2. Inspect the wrapped ENOTDIR/EACCES error path; remove the file blocking the directory path.
  3. Fix ownership/permissions on the output directory so the current user can create directories.
  4. Verify the relative path in requirements.txt (e.g. `./core`) matches an actual directory in the workspace root.

Example fix

// before
Error: failed to create directory for workspace package ./packages/core: mkdir /out/packages: not a directory
// after
$ rm -rf .sst   # removes stale file blocking the path
$ sst deploy
Defensive patterns

Strategy: validation

Validate before calling

// before deploy: ensure output paths are directories or absent
for (const rel of ['packages/core']) {
  const dest = path.join(buildOut, rel);
  if (fs.existsSync(dest) && !fs.statSync(dest).isDirectory()) throw new Error(`${dest} is a file; clean .sst`);
}
fs.accessSync(buildOut, fs.constants.W_OK);

Type guard

null

Try / catch

try {
  await deploy();
} catch (e) {
  if (/failed to create directory for workspace package/.test(e.message)) {
    fs.rmSync('.sst', { recursive: true, force: true });
    await deploy();
  } else throw e;
}

Prevention

When it happens

Trigger: os.MkdirAll(filepath.Dir(destPath), 0755) fails in copyWorkspacePackagesForContainer when a component of destPath (inside input.Out()) exists as a regular file, or the output directory is not writable.

Common situations: Stale/corrupt .sst build output where a previous build left a file at a path now needed as a directory; running deploy as a different user than a previous build; workspace package path like `./pkg` colliding with an existing file in the output.

Related errors


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