HKUDS/Vibe-Trading · critical · TigerProfileMismatchError

Configured profile is live, but the account number is a 17-d

Error message

Configured profile is live, but the account number is a 17-digit Tiger paper account. Select a paper profile for paper accounts.

What it means

The inverse of the paper mismatch: _assert_profile raises TigerProfileMismatchError when profile is 'live' but is_paper_account(account) is true, i.e. the configured account is a 17-digit paper account. This blocks code that believes it is operating on a live account from silently running against the paper environment.

Source

Thrown at agent/src/trading/connectors/tiger/sdk.py:603

    _require_tigeropen()
    from tigeropen.quote.quote_client import QuoteClient  # type: ignore

    return QuoteClient(_client_config(cfg))


def _assert_profile(cfg: TigerConfig) -> None:
    """Fail closed when the account does not match the declared environment."""
    account = (cfg.account or "").strip()
    if not account:
        raise TigerConfigError("Tiger account number is not configured")
    paper = is_paper_account(account)
    if cfg.environment == "paper" and not paper:
        raise TigerProfileMismatchError(
            "Configured profile is paper, but the account number is not a 17-digit Tiger paper account. "
            "Use a live profile only if you intend live-account access."
        )
    if cfg.environment == "live" and paper:
        raise TigerProfileMismatchError(
            "Configured profile is live, but the account number is a 17-digit Tiger paper account. "
            "Select a paper profile for paper accounts."
        )


def _missing_fields(cfg: TigerConfig) -> list[str]:
    missing = []
    if not cfg.tiger_id:
        missing.append("tiger_id")
    if not cfg.private_key_path:
        missing.append("private_key_path")
    if not cfg.account:
        missing.append("account")
    return missing


def _public_config(cfg: TigerConfig) -> dict[str, Any]:
    """Config snapshot with credential material masked (key path only, never contents)."""

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. If you intend paper trading, set profile back to 'paper' to match the 17-digit account
  2. If you intend live, replace account with your real live account number from the Tiger portal
  3. Keep one config file per environment to avoid half-migrated edits

Example fix

// before
{"profile": "live", "account": "20190129101234567"}  // 17-digit paper account

// after
{"profile": "paper", "account": "20190129101234567"}
Defensive patterns

Strategy: validation

Validate before calling

from agent.src.trading.connectors.tiger.sdk import is_paper_account

def live_profile_is_really_live(cfg) -> bool:
    return not (cfg.environment == 'live' and is_paper_account((cfg.account or '').strip()))

Type guard

def assert_live_not_paper(cfg: TigerConfig) -> None:
    if cfg.environment == 'live' and is_paper_account(cfg.account.strip()):
        raise ValueError('live profile configured with a paper account number')

Try / catch

try:
    place_or_read_live(cfg)
except TigerProfileMismatchError as exc:
    logger.critical('Refusing to proceed: %s', exc)
    abort_run()

Prevention

When it happens

Trigger: Any Tiger operation with profile='live' (or 'live-readonly' is not checked here — only 'live' triggers this branch) while cfg.account is a 17-digit Tiger paper account number.

Common situations: Switching a config from paper to live by editing only the profile and forgetting to update the account; reusing paper credentials after a go-live; account field populated from a paper fixture during a production deploy.

Related errors


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