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 missing

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Set cfg.host (or the env feeding it) to exactly the testnet_host value the config declares
  2. Compare urlparse(host).hostname and urlparse(testnet_host).hostname in a config sanity check at startup
  3. Upgrade/pin the library so testnet_host constant matches the current Binance testnet domain
  4. 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

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


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/94c948d3938e2d73. Report an issue: GitHub.