HKUDS/Vibe-Trading · critical · TigerProfileMismatchError

Configured profile is paper, but the account number is not a

Error message

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.

What it means

_assert_profile cross-checks the declared profile against the account number shape: Tiger paper accounts are 17-digit numbers (detected via is_paper_account). When profile is 'paper' but the account does not match the paper pattern, it raises TigerProfileMismatchError to prevent accidentally hitting a live account under paper assumptions.

Source

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

    return TradeClient(_client_config(cfg))


def _quote_client(cfg: TigerConfig):
    _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")

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. If you meant live trading/read-only, change profile to 'live-readonly' or 'live' to match the account
  2. If you meant paper, replace account with your Tiger paper account number (17 digits) from the paper-trading section of the portal
  3. Double-check the account string for missing/extra digits (must be exactly 17 digits for paper)

Example fix

// before
{"profile": "paper", "account": "35126589"}  // live account under paper profile

// after
{"profile": "live-readonly", "account": "35126589"}
Defensive patterns

Strategy: validation

Validate before calling

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

def profile_matches_account(cfg) -> bool:
    paper = is_paper_account((cfg.account or '').strip())
    if cfg.environment == 'paper':
        return paper
    return True

Type guard

def is_paper_account(account: str) -> bool:
    return bool(account) and account.isdigit() and len(account) == 17

Try / catch

try:
    get_positions(cfg)
except TigerProfileMismatchError as exc:
    logger.error('Profile/account mismatch: %s', exc)
    # stop and require human confirmation before changing anything

Prevention

When it happens

Trigger: Any Tiger operation (check_status, get_positions, get_quote, ...) with profile='paper' while cfg.account is a real live account number (not 17-digit paper format), or a paper account number that was mistyped so it no longer matches the 17-digit pattern.

Common situations: Copying a live account number into a config while leaving profile 'paper' (the default); misunderstanding that paper mode requires Tiger's dedicated paper account, not your live credentials; typos truncating the 17-digit paper account id.

Related errors


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