HKUDS/Vibe-Trading · error · ValueError

period must be string, got {type(period).__name__}

Error message

period must be string, got {type(period).__name__}

What it means

_parse_period in alpha_bench_tool requires the period argument to be a str. Passing any other type (int, None, dict, datetime) raises this immediately, before regex matching is attempted.

Source

Thrown at agent/src/tools/alpha_bench_tool.py:83

# Universe + period parsing
# ---------------------------------------------------------------------------

_PERIOD_YEAR = re.compile(r"^(\d{4})-(\d{4})$")
_PERIOD_DATE = re.compile(r"^(\d{4}-\d{2}-\d{2})/(\d{4}-\d{2}-\d{2})$")

# Universe → (market_key, universe_meta_tag). Only the listed universes have a
# defined contract; everything else returns "not yet implemented".
_UNIVERSE_TAG = {
    "csi300": "equity_cn",
    "sp500": "equity_us",
    "btc-usdt": "crypto",
}


def _parse_period(period: str) -> tuple[str, str]:
    """Return (start_date, end_date) as YYYY-MM-DD strings."""
    if not isinstance(period, str):
        raise ValueError(f"period must be string, got {type(period).__name__}")
    m = _PERIOD_DATE.match(period)
    if m:
        start, end = m.group(1), m.group(2)
    else:
        m = _PERIOD_YEAR.match(period)
        if m:
            start, end = f"{m.group(1)}-01-01", f"{m.group(2)}-12-31"
        else:
            raise ValueError(
                f"period {period!r} must be YYYY-YYYY or YYYY-MM-DD/YYYY-MM-DD"
            )
    # Match backtest loaders.validate_date_range: reject inverted ranges.
    if pd.Timestamp(start) > pd.Timestamp(end):
        raise ValueError(f"start_date ({start}) > end_date ({end})")
    return start, end


def _load_universe_panel(

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Convert the value to str before calling (e.g. str(period) for scalars)
  2. Add a JSON-schema 'type':'string' constraint on the tool's period parameter
  3. Default the parameter explicitly (e.g. '2020-2023') instead of letting None through

Example fix

// before
result = alpha_bench(universe='csi300', period=None)
// after
result = alpha_bench(universe='csi300', period='2020-2023')
Defensive patterns

Strategy: type-guard

Validate before calling

period = period if isinstance(period, str) else str(period)
assert isinstance(period, str) and period

Type guard

def is_period_str(p: object) -> bool:
    return isinstance(p, str) and len(p) > 0

Try / catch

try:
    alpha_bench(universe=u, period=period)
except ValueError as e:
    if 'period must be string' in str(e):
        period = str(period); retry()
    else: raise

Prevention

When it happens

Trigger: Calling alpha_bench / kick_off_bench / kick_off_compare / _load_universe_panel with period=None, period=2023, or a pandas Timestamp / datetime object instead of a string.

Common situations: Tool schemas where the LLM emits a number for a year-only period; passing datetime objects from downstream code; optional kwargs that default to None being forwarded unconditionally.

Understand the failure class

Background: "Wrong argument type", "must be a string", "expected Array or Prism::Scope": TypeError and ArgumentError when a library receives a value of the wrong type — this error's family across 28 libraries.

Related errors


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