pulumi/pulumi · error · FileNotFoundError

failed to find project settings file in workdir: {work_dir}

Error message

failed to find project settings file in workdir: {work_dir}

What it means

LocalWorkspace.get_project_settings iterates over the known project settings filenames (Pulumi.yaml, Pulumi.json, Pulumi.yml) in the given work directory and loads the first one it finds. If none of these files exists, it raises FileNotFoundError. This guards downstream operations that require project metadata (project name, runtime, etc.) which would otherwise fail with more confusing errors.

Source

Thrown at sdk/python/lib/pulumi/automation/_local_workspace.py:1081

    return ProjectSettings(name=project_name, runtime="python", main=os.getcwd())


def get_stack_settings_name(name: str) -> str:
    parts = name.split("/")
    if len(parts) < 1:
        return name
    return parts[-1]


def _load_project_settings(work_dir: str) -> ProjectSettings:
    for ext in _setting_extensions:
        project_path = os.path.join(work_dir, f"Pulumi{ext}")
        if not os.path.exists(project_path):
            continue
        with open(project_path, encoding="utf-8") as file:
            settings = json.load(file) if ext == ".json" else yaml.safe_load(file)
            return ProjectSettings.from_dict(settings)
    raise FileNotFoundError(
        f"failed to find project settings file in workdir: {work_dir}"
    )

View on GitHub (pinned to 793f7b2e16)

Solutions

  1. Point LocalWorkspace work_dir at the directory that actually contains Pulumi.yaml (or Pulumi.json/.yml)
  2. Create the project settings file with `pulumi new` or by writing a minimal Pulumi.yaml
  3. Check os.path.exists for the settings file before constructing the workspace
  4. Verify the file uses a supported extension: .yaml, .yml, or .json

Example fix

// before
ws = LocalWorkspace(work_dir="/tmp/scratch")
settings = ws.get_project_settings()
// after
ws = LocalWorkspace(work_dir="/path/to/project")  # contains Pulumi.yaml
settings = ws.get_project_settings()
Defensive patterns

Strategy: validation

Validate before calling

import os
for ext in (".yaml", ".yml", ".json"):
    if os.path.exists(os.path.join(work_dir, f"Pulumi{ext}")):
        break
else:
    raise FileNotFoundError(f"no Pulumi project settings in {work_dir}")

Type guard

def has_project_settings(work_dir: str) -> bool:
    return any(os.path.exists(os.path.join(work_dir, f"Pulumi{ext}"))
               for ext in (".yaml", ".yml", ".json"))

Try / catch

try:
    settings = ws.get_project_settings()
except FileNotFoundError:
    settings = None  # or prompt user to run `pulumi new`

Prevention

When it happens

Trigger: Calling LocalWorkspace methods that read project settings (e.g. get_project_settings(), or operations that lazily load settings such as stack name parsing) against a directory that contains no Pulumi.yaml/Pulumi.yml/Pulumi.json file.

Common situations: Passing the wrong work_dir to LocalWorkspace (parent directory instead of the project root); running from a temp/scratch directory; project settings file renamed or deleted; Pulumi.yaml stored with an unusual extension.

Related errors


AI-assisted analysis of pulumi/pulumi@793f7b2e16 (2026-08-31). Data as JSON: /api/errors/1587d78048530bc4. Report an issue: GitHub.