headroomlabs-ai/headroom · error · ValueError
deployment env missing {self.config_env_var}
Error message
deployment env missing {self.config_env_var} What it means
ValueError raised by DeploymentSpec.validate() in headroom/testing/harness.py when the deployment environment dict (self.env) does not contain the config env var (self.config_env_var, default 'HEADROOM_PROXY_CONFIG_JSON'). validate() exists to prove the environment round-trips the full config payload — the child process is expected to receive its config through that single env var — so a missing var means the deployment is not wired correctly.
Source
Thrown at headroom/testing/harness.py:395
command: tuple[str, ...]
env: dict[str, str]
config_payload: dict[str, Any]
config_env_var: str = "HEADROOM_PROXY_CONFIG_JSON"
def to_dict(self) -> dict[str, Any]:
return {
"command": list(self.command),
"env": dict(self.env),
"config_payload": dict(self.config_payload),
"config_env_var": self.config_env_var,
}
def validate(self) -> None:
"""Fail if the environment does not round-trip the full config payload."""
raw = self.env.get(self.config_env_var)
if raw is None:
raise ValueError(f"deployment env missing {self.config_env_var}")
parsed = json.loads(raw)
if parsed != self.config_payload:
raise ValueError(f"{self.config_env_var} does not match config_payload")
def _field_contract(
owner: Literal["headroom", "proxy"], cls: type[Any]
) -> tuple[FieldContract, ...]:
if not is_dataclass(cls):
raise TypeError(f"{cls!r} must be a dataclass")
out: list[FieldContract] = []
for field in cls.__dataclass_fields__.values():
default: Any = MISSING
if field.default is not MISSING:
default = field.default
elif field.default_factory is not MISSING: # type: ignore[attr-defined]
default = "<factory>"
out.append(View on GitHub (pinned to 322425c43b)
Solutions
- Ensure the config var is present: spec.env[spec.config_env_var] = json.dumps(spec.config_payload).
- If you filtered/copied env, re-add the config var afterwards or stop filtering HEADROOM_* variables.
- Run spec.validate() early (right after building the spec) to catch this before launching the deployment.
Example fix
# before
spec = DeploymentSpec(env={**os.environ}, ...) # HEADROOM_PROXY_CONFIG_JSON dropped
spec.validate() # ValueError
# after
spec.env['HEADROOM_PROXY_CONFIG_JSON'] = json.dumps(spec.config_payload)
spec.validate() Defensive patterns
Strategy: validation
Validate before calling
def env_carries_config(spec) -> bool:
return spec.config_env_var in spec.env and spec.env[spec.config_env_var] is not None Try / catch
try:
spec.validate()
except ValueError as e:
if 'missing' in str(e):
spec.env[spec.config_env_var] = json.dumps(spec.config_payload)
spec.validate()
else:
raise Prevention
- Call validate() before spawning the child process.
- Treat the config env var as mandatory in env sanitizers.
When it happens
Trigger: Building a DeploymentSpec with env={'FOO': '1'} but never injecting the config var; stripping env vars with a sanitizer/filter that drops HEADROOM_*; serializing the spec to JSON (to_dict) and reconstructing it without restoring the config env var.
Common situations: Test harnesses that copy a base environment and filter variables; subprocess wrappers applying an env allowlist; CI runners with restricted env propagation.
Related errors
- {self.config_env_var} does not match config_payload
- offline mode (HEADROOM_BINARIES_OFFLINE=1) but fetch require
- OPENAI_API_KEY environment variable required
- Unsupported platform: {system} {machine}
- `{cmd[0]}` not found in PATH. Install it or use a different
AI-assisted analysis of headroomlabs-ai/headroom@322425c43b (2026-08-15).
Data as JSON: /api/errors/d12df42c0675a90d.
Report an issue: GitHub.