headroomlabs-ai/headroom · error · ValueError

Windows environment mutation is missing a valid scope

Error message

Windows environment mutation is missing a valid scope

What it means

Raised in _remove_windows_env_scope when a windows-env mutation's 'scope' field is present but not a string (it defaults to 'User' when absent, so this fires only on explicitly wrong types like scope: 1 or scope: null-that-was-loaded-as-non-str). The scope is passed to PowerShell's [Environment]::SetEnvironmentVariable as the third argument and must be the literal 'User', 'Machine', or 'Process'; a non-string cannot be safely interpolated, so rollback aborts.

Source

Thrown at headroom/install/providers.py:135

                    "name": name,
                    "scope": scope_name,
                    "previous": None if previous == "__HEADROOM_UNSET__" else previous,
                },
            )
        )
    return mutations


def _remove_windows_env_scope(mutations: list[ManagedMutation]) -> None:
    for mutation in mutations:
        if mutation.kind != "windows-env":
            continue
        name = mutation.data.get("name")
        if not isinstance(name, str):
            raise ValueError("Windows environment mutation is missing a variable name")
        scope_name = mutation.data.get("scope", "User")
        if not isinstance(scope_name, str):
            raise ValueError("Windows environment mutation is missing a valid scope")
        previous = mutation.data.get("previous")
        if previous is None:
            value_literal = "$null"
        else:
            value_literal = _powershell_literal(previous)
        command = [
            "powershell",
            "-NoProfile",
            "-Command",
            f"[Environment]::SetEnvironmentVariable({_powershell_literal(name)},{value_literal},{_powershell_literal(scope_name)})",
        ]
        subprocess.run(command, check=True)


def apply_mutations(manifest: DeploymentManifest) -> list[ManagedMutation]:
    """Apply provider/user/system configuration for a deployment."""

    mutations: list[ManagedMutation] = []

View on GitHub (pinned to 322425c43b)

Solutions

  1. Edit the mutation in manifest.json so "scope" is one of the strings "User", "Machine", or "Process" (matching how the value was originally set).
  2. If unsure of the original scope, check what the install step used (installers almost always use 'User' on Windows for per-user installs).
  3. Remove the malformed mutation entry and revert the variable manually in PowerShell.
  4. Reinstall cleanly to regenerate the manifest if multiple entries are damaged.

Example fix

// before
{"kind": "windows-env", "data": {"name": "HEADROOM_HOME", "scope": 1, "previous": null}}

// after
{"kind": "windows-env", "data": {"name": "HEADROOM_HOME", "scope": "User", "previous": null}}
Defensive patterns

Strategy: validation

Validate before calling

VALID_SCOPES = {"User", "Machine", "Process"}

for m in manifest.mutations:
    if m.kind == "windows-env":
        scope = m.data.get("scope", "User")
        assert isinstance(scope, str) and scope in VALID_SCOPES, f"bad scope {scope!r} in {m.data!r}"

Type guard

def has_valid_windows_scope(mutation) -> bool:
    scope = mutation.data.get("scope", "User") if mutation.kind == "windows-env" else None
    return isinstance(scope, str) and scope in {"User", "Machine", "Process"}

Try / catch

try:
    uninstall(profile)
except ValueError as e:
    if "missing a valid scope" in str(e):
        fix_scope_in_manifest(manifest_path)  # set "scope": "User"
        uninstall(profile)
    else:
        raise

Prevention

When it happens

Trigger: A manifest.json hand-edited or emitted by a buggy version where "scope" is a number/boolean/list; e.g. {"scope": 1} or {"scope": ["User"]}. Distinct from error 152: the name validated fine, only the scope is malformed.

Common situations: Schema drift between headroom versions (scope introduced later); JSON produced by scripts that coerce values; manual edits attempting to switch User->Machine scope incorrectly.

Related errors


AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15). Data as JSON: /api/errors/6d5374f740e21659. Report an issue: GitHub.