can1357/oh-my-pi · error · ValueError
ROBOMP_GH_PROXY_URL and ROBOMP_GH_PROXY_HMAC_KEY must both b
Error message
ROBOMP_GH_PROXY_URL and ROBOMP_GH_PROXY_HMAC_KEY must both be set together (or both empty).
What it means
The _validate_proxy_or_pat() model validator requires ROBOMP_GH_PROXY_URL and ROBOMP_GH_PROXY_HMAC_KEY to be set together: proxy mode without the HMAC key cannot sign requests, and an HMAC key without a URL has nowhere to send them. A mismatch (has_url != has_key) raises ValueError.
Source
Thrown at python/robomp/src/config.py:247
def _validate_proxy_or_pat(self) -> Settings:
"""Enforce mutual exclusion between PAT and proxy mode.
- Both set → reject (silent fallback to direct GitHub would defeat
the isolation goal).
- Proxy URL set but no HMAC key (or vice versa) → reject (gh-proxy
would either be unauthenticated or unreachable).
- Neither set → also reject; SOMETHING needs to talk to GitHub.
"""
has_token = self.github_token is not None
has_url = bool(self.gh_proxy_url)
has_key = self.gh_proxy_hmac_key is not None
if has_token and has_url:
raise ValueError(
"GITHUB_TOKEN and ROBOMP_GH_PROXY_URL are mutually exclusive — "
"set ONE to choose between direct-PAT and gh-proxy modes."
)
if has_url != has_key:
raise ValueError(
"ROBOMP_GH_PROXY_URL and ROBOMP_GH_PROXY_HMAC_KEY must both be set together (or both empty)."
)
if not has_token and not has_url:
raise ValueError(
"no GitHub access configured: set GITHUB_TOKEN, or set "
"ROBOMP_GH_PROXY_URL + ROBOMP_GH_PROXY_HMAC_KEY to use gh-proxy."
)
return self
@field_validator("repo_allowlist_raw", mode="before")
@classmethod
def _coerce_allowlist(cls, v: object) -> str:
if v is None:
return ""
if isinstance(v, str):
return v
if isinstance(v, (list, tuple)):
return ",".join(str(item) for item in v)View on GitHub (pinned to 9690622007)
Solutions
- Set both ROBOMP_GH_PROXY_URL and ROBOMP_GH_PROXY_HMAC_KEY together.
- If you don't intend to use gh-proxy, remove both variables and configure GITHUB_TOKEN instead.
- Check secret injection so the HMAC key is actually mounted/interpolated.
- Verify exact env var spelling in .env and deployment manifests.
Example fix
// before ROBOMP_GH_PROXY_URL=http://gh-proxy:8080 # ROBOMP_GH_PROXY_HMAC_KEY missing // after ROBOMP_GH_PROXY_URL=http://gh-proxy:8080 ROBOMP_GH_PROXY_HMAC_KEY=<shared-secret>
Defensive patterns
Strategy: validation
Validate before calling
import os
has_url, has_key = bool(os.environ.get("ROBOMP_GH_PROXY_URL")), bool(os.environ.get("ROBOMP_GH_PROXY_HMAC_KEY"))
if has_url != has_key:
raise SystemExit("ROBOMP_GH_PROXY_URL and ROBOMP_GH_PROXY_HMAC_KEY must be set together") Type guard
def proxy_pair_complete(env: dict) -> bool:
return bool(env.get("ROBOMP_GH_PROXY_URL")) == bool(env.get("ROBOMP_GH_PROXY_HMAC_KEY")) Try / catch
try:
cfg = Settings(_env_file=".env")
except ValidationError as exc:
sys.exit(f"configuration error: {exc}") Prevention
- Store the URL and HMAC key adjacent in the same config file/secret set so they ship together.
- Wire secret-store values into env explicitly — don't assume defaults.
- Watch for key rotation scripts that update one variable but not the other.
When it happens
Trigger: Constructing Settings with gh_proxy_url set but gh_proxy_hmac_key missing, or the key set while the URL is empty/absent.
Common situations: Only the URL added to .env (the key was meant to come from a secret store but was not wired); key rotation removed one variable; typo in one of the two names; partial copy-paste of a config snippet.
Related errors
- GITHUB_TOKEN and ROBOMP_GH_PROXY_URL are mutually exclusive
- ROBOMP_BOT_LOGIN must be a non-empty GitHub login
- robomp orchestrator refuses to start with GITHUB_TOKEN set i
- robomp orchestrator requires ROBOMP_GH_PROXY_URL and ROBOMP_
- no GitHub access configured: set GITHUB_TOKEN, or set ROBOMP
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/fb2a1b90bbfd1182.
Report an issue: GitHub.