anomalyco/sst · error

failed to read pyproject.toml at %s: %w

Error message

failed to read pyproject.toml at %s: %w

What it means

parsePyprojectToml fails when os.ReadFile cannot read the pyproject.toml at the given path. The path is included in the message and the OS error is wrapped with %w. Callers include findWorkspaceRoot, generateOrCopyRequirementsFile, getWorkspacePackageNames, copyDependencyPackages, discoverBuildablePackages and buildableFromPaths, so this aborts workspace discovery and dependency staging.

Source

Thrown at pkg/runtime/python/project.go:175

// resolveSourceRoot determines the source root directory.
func resolveSourceRoot(projectRoot, pyprojectPath string) string {
	if pyprojectPath != "" {
		pyprojectDir := filepath.Dir(pyprojectPath)
		srcDir := filepath.Join(pyprojectDir, "src")
		if _, err := os.Stat(srcDir); err == nil {
			return srcDir
		}
		return pyprojectDir
	}
	return projectRoot
}

// parsePyprojectToml reads and parses a pyproject.toml file.
func parsePyprojectToml(path string) (*pyprojectConfig, error) {
	content, err := os.ReadFile(path)
	if err != nil {
		return nil, fmt.Errorf("failed to read pyproject.toml at %s: %w", path, err)
	}

	var config pyprojectConfig
	if err := toml.Unmarshal(content, &config); err != nil {
		return nil, fmt.Errorf("TOML parsing error in %s: %w", path, err)
	}

	return &config, nil
}

View on GitHub (pinned to a0bd20f762)

Solutions

  1. Read the wrapped %w OS error to identify the precise cause (ENOENT, EACCES, EISDIR).
  2. Fix file permissions: chmod u+r pyproject.toml (and ensure parent dirs are readable).
  3. If it's a symlink or directory, replace it with a real pyproject.toml file.
  4. Re-run the command after any concurrent git/process activity on the repo settles.

Example fix

// before
$ ls -l pyproject.toml
lrwxr-xr-x pyproject.toml -> /nonexistent

// after (shell)
$ rm pyproject.toml && git checkout -- pyproject.toml
$ chmod u+r pyproject.toml
Defensive patterns

Strategy: try-catch

Validate before calling

// shell
test -f pyproject.toml && test -r pyproject.toml && ! test -d pyproject.toml && echo OK || echo 'pyproject.toml unreadable or not a file'

Try / catch

try { await deploy() } catch (e) {
  if (String(e).includes("failed to read pyproject.toml")) {
    const os = e.cause ?? e; // wrapped %w
    console.error("Fix read error for pyproject.toml:", os);
  }
  throw e;
}

Prevention

When it happens

Trigger: pyproject.toml path exists in the resolver's view but reading fails: file deleted between discovery and read, permission denied, path is a directory, or a broken symlink.

Common situations: Read-only checkout or CI runner with restrictive file permissions; pyproject.toml is a symlink pointing to a missing file; a directory literally named pyproject.toml from a bad generation script; race with git operations (checkout/clean) during deploy.

Related errors


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