HKUDS/Vibe-Trading · critical · BinanceConfigError
Configured profile is paper, but the resolved host '{host}'
Error message
Configured profile is paper, but the resolved host '{host}' is not the testnet host '{expected}'. What it means
_assert_host fail-closes when the config declares paper/testnet (cfg.is_testnet) but the parsed hostname of cfg.host does not equal the parsed hostname of cfg.testnet_host. It prevents a testnet-labeled profile from silently hitting any other host (including live). Raised before any network call in check_status, get_account_snapshot, get_positions, get_open_orders, get_quote, and get_historical_bars.
Source
Thrown at agent/src/trading/connectors/binance/sdk.py:757
try:
assert_exchange_endpoints(ex)
except UsdMObservationError as exc:
raise BinanceConfigError(str(exc)) from None
return ex
def _assert_host(cfg: BinanceConfig) -> None:
"""Fail closed when the resolved host does not match the declared environment.
The host is the authoritative discriminator: testnet keys cannot reach the
live host. A live profile must resolve to ``api.binance.com``; a paper
profile must resolve to the configured testnet host.
"""
host = (urlparse(cfg.host).hostname or cfg.host or "").lower()
if cfg.is_testnet:
expected = (urlparse(cfg.testnet_host).hostname or cfg.testnet_host or "").lower()
if host != expected:
raise BinanceConfigError(
f"Configured profile is paper, but the resolved host '{host}' is not the testnet host '{expected}'."
)
return
expected_url = USDM_LIVE_HOST if cfg.market_type == "usdm" else LIVE_HOST
expected = urlparse(expected_url).hostname or expected_url
if host != expected:
raise BinanceConfigError(
f"Configured profile is live, but the resolved host '{host}' is not the live host '{expected}'."
)
def _missing_fields(cfg: BinanceConfig) -> list[str]:
missing = []
if not cfg.api_key:
missing.append("api_key")
if not cfg.api_secret:
missing.append("api_secret")
return missingView on GitHub (pinned to 80ffdda44c)
Solutions
- Set cfg.host (or the env feeding it) to exactly the testnet_host value the config declares
- Compare urlparse(host).hostname and urlparse(testnet_host).hostname in a config sanity check at startup
- Upgrade/pin the library so testnet_host constant matches the current Binance testnet domain
- Audit environment precedence: the paper profile must resolve host from the testnet setting, not from a live-host override
Example fix
# before cfg = BinanceConfig(host="https://fapi.binance.com", is_testnet=True, testnet_host="https://testnet.binancefuture.com") # after cfg = BinanceConfig(host=cfg.testnet_host, is_testnet=True, testnet_host="https://testnet.binancefuture.com")
Defensive patterns
Strategy: validation
Validate before calling
from urllib.parse import urlparse
host = (urlparse(cfg.host).hostname or '').lower()
expected = (urlparse(cfg.testnet_host).hostname or '').lower()
if cfg.is_testnet and host != expected:
raise SystemExit(f'paper profile must use {expected}, got {host}') Type guard
def is_paper_host_consistent(cfg) -> bool:
return not cfg.is_testnet or (urlparse(cfg.host).hostname or '').lower() == (urlparse(cfg.testnet_host).hostname or '').lower() Try / catch
try:
sdk.check_status(cfg)
except BinanceConfigError as exc:
if 'not the testnet host' in str(exc):
cfg = replace(cfg, host=cfg.testnet_host)
sdk.check_status(cfg)
else:
raise Prevention
- Derive host from the profile: paper => testnet_host, live => canonical live host
- Single-source the host env var; audit overrides at startup
- Add config lint that asserts hostname equality for paper profiles
When it happens
Trigger: cfg.is_testnet=True with cfg.host pointing at the live host, a placeholder, localhost, an empty string, or a differently-spelled testnet hostname (e.g. 'testnet.binancefuture.com' vs the configured testnet_host value). Also when cfg.host contains a scheme/port that changes the parsed hostname.
Common situations: Env var for host set for live while profile env says paper; copy-pasted config where host and testnet_host disagree; testnet host constant changed across library versions leaving stale configs; trailing path or port in host string altering urlparse().hostname.
Related errors
- Configured profile is live, but the resolved host '{host}' i
- {exc}
- webhook_secret_token is required when Telegram mode is webho
- unix_socket_path must not contain NUL bytes
- unix_socket_path must be an absolute path
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/94c948d3938e2d73.
Report an issue: GitHub.