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
- Edit the mutation in manifest.json so "scope" is one of the strings "User", "Machine", or "Process" (matching how the value was originally set).
- If unsure of the original scope, check what the install step used (installers almost always use 'User' on Windows for per-user installs).
- Remove the malformed mutation entry and revert the variable manually in PowerShell.
- 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
- Keep "scope" as a JSON string ('User'/'Machine'/'Process') — never numbers or arrays.
- Validate the whole manifest with a small schema check after any manual edit.
- Upgrade headroom and manifests together to avoid schema drift between versions.
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
- Windows environment mutation is missing a variable name
- invalid pipeline config TOML: {0}
- recommendations file not found: {0}
- bedrock_eventstream_parse_failed
- items_json must be JSON: {e}
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/6d5374f740e21659.
Report an issue: GitHub.