anomalyco/sst · error

failed to read workspace directory: %w

Error message

failed to read workspace directory: %w

What it means

After copying handler directories, copySourceFilesSimple lists the workspace directory with os.ReadDir to copy root-level .py files into the build output. This error is returned when the workspace directory itself cannot be read. It wraps the OS error (ENOENT, EACCES, ENOTDIR).

Source

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

			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 {
				return fmt.Errorf("failed to copy file %s: %w", entry.Name(), err)
			}
		}
	}

	return nil
}

// copySyncedDependencies installs dependencies with correct platform targeting
func copySyncedDependencies(ctx context.Context, input *runtime.BuildInput, projectInfo *projectInfo, architecture string) error {
	requirementsPath := filepath.Join(input.Out(), "requirements.txt")

	if _, err := os.Stat(requirementsPath); os.IsNotExist(err) {
		slog.Warn("requirements.txt not found, skipping dependency installation", "path", requirementsPath)

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Verify the pyproject.toml / workspace root path exists: `ls <projectRoot>/pyproject.toml`; fix config or restore the directory.
  2. Run `sst deploy` from the app root so projectInfo paths resolve correctly.
  3. Check permissions on the workspace directory (`chmod u+rx <workspaceDir>`).
  4. Clean and regenerate build state: `rm -rf .sst` and redeploy.

Example fix

// before
Error: failed to copy source files: failed to read workspace directory: open /app/packages/api: no such file or directory
// after
$ cd /app && ls packages/api/pyproject.toml  # fix path or restore dir
$ sst deploy
Defensive patterns

Strategy: validation

Validate before calling

const wsDir = path.dirname(pyprojectPath); // what SST derives
if (!fs.existsSync(wsDir)) throw new Error(`workspace dir ${wsDir} missing — check pyproject.toml location`);
fs.accessSync(wsDir, fs.constants.R_OK | fs.constants.X_OK);

Type guard

null

Try / catch

try {
  await deploy();
} catch (e) {
  if (/failed to read workspace directory/.test(e.message)) {
    console.error('Workspace root missing/unreadable — verify pyproject.toml path and run from app root');
    throw e;
  } else throw e;
}

Prevention

When it happens

Trigger: os.ReadDir(workspaceDir) fails when projectInfo.SourceRoot / the directory containing pyproject.toml does not exist, was deleted, or is not readable — e.g. a misconfigured pyproject path or a workspace root that is actually a file.

Common situations: pyproject.toml moved/renamed so the derived workspace dir no longer exists; running deploy from the wrong working directory; project root renamed without updating config; symlinked workspace pointing to a deleted location.

Related errors


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