can1357/oh-my-pi · error · ValueError
GITHUB_TOKEN and ROBOMP_GH_PROXY_URL are mutually exclusive
Error message
GITHUB_TOKEN and ROBOMP_GH_PROXY_URL are mutually exclusive — set ONE to choose between direct-PAT and gh-proxy modes.
What it means
The Settings model validator _validate_proxy_or_pat() enforces exactly one GitHub access mode: a direct PAT (GITHUB_TOKEN) or the gh-proxy pair (ROBOMP_GH_PROXY_URL + HMAC key). Setting both is ambiguous and rejected with ValueError during model validation.
Source
Thrown at python/robomp/src/config.py:242
if isinstance(inner, str) and not inner.strip():
return None
return value
@model_validator(mode="after")
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:View on GitHub (pinned to 9690622007)
Solutions
- Remove GITHUB_TOKEN from the environment when using gh-proxy mode.
- Or remove ROBOMP_GH_PROXY_URL/ROBOMP_GH_PROXY_HMAC_KEY when using direct-PAT mode.
- Audit env layering (.env, shell, container env, CI) for stray variables.
- Print effective config (redacted) at startup to catch mixed modes early.
Example fix
// before GITHUB_TOKEN=ghp_xxx ROBOMP_GH_PROXY_URL=http://gh-proxy:8080 // after (proxy mode) ROBOMP_GH_PROXY_URL=http://gh-proxy:8080 ROBOMP_GH_PROXY_HMAC_KEY=<key>
Defensive patterns
Strategy: validation
Validate before calling
import os
mode = sum(bool(x) for x in (os.environ.get("GITHUB_TOKEN"), os.environ.get("ROBOMP_GH_PROXY_URL")))
if mode > 1:
raise SystemExit("Set exactly one GitHub access mode: GITHUB_TOKEN or the gh-proxy pair") Type guard
def has_single_github_mode(env: dict) -> bool:
return bool(env.get("GITHUB_TOKEN")) != bool(env.get("ROBOMP_GH_PROXY_URL")) Try / catch
try:
cfg = Settings(_env_file=".env")
except ValidationError as exc:
sys.exit(f"configuration error: {exc}") Prevention
- When migrating between PAT and proxy modes, delete the old variable, don't just add new ones.
- Audit env layering (shell profile, CI globals, container env) for stray GITHUB_TOKEN.
- Keep one canonical .env per deployment mode.
When it happens
Trigger: Constructing Settings (from env or programmatically) with both github_token and gh_proxy_url set — e.g. GITHUB_TOKEN present in base env plus ROBOMP_GH_PROXY_URL in a .env file.
Common situations: Migrating from direct-PAT to gh-proxy mode without removing the old token; inheriting host env into containers; CI injecting GITHUB_TOKEN globally while the job configures proxy mode.
Related errors
- ROBOMP_GH_PROXY_URL and ROBOMP_GH_PROXY_HMAC_KEY must both b
- 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/153b6db701f23238.
Report an issue: GitHub.