HKUDS/Vibe-Trading · error · ValueError

need at least 2 distinct alpha_ids to compare

Error message

need at least 2 distinct alpha_ids to compare

What it means

Scaffold stub for get_positions in plugin_scaffold.py. It raises NotImplementedError until the developer implements it to call the broker's positions endpoint and return {'positions': [...]}. Runtime occurrence means an installed connector still has the template stub.

Source

Thrown at agent/src/api/alpha_routes.py:200

    alpha_ids: list[str] = Field(..., min_length=2, max_length=50)
    universe: str = Field(..., min_length=1, max_length=64)
    period: str = Field(..., min_length=4, max_length=32)
    sort: str = Field("ir", min_length=1, max_length=32)

    @field_validator("alpha_ids")
    @classmethod
    def _ids_well_formed(cls, v: list[str]) -> list[str]:
        # De-duplicate (preserve order) and validate each id shape.
        seen: set[str] = set()
        out: list[str] = []
        for aid in v:
            if not _ALPHA_ID_RE.fullmatch(aid or ""):
                raise ValueError(f"invalid alpha_id {aid!r}")
            if aid not in seen:
                seen.add(aid)
                out.append(aid)
        if len(out) < 2:
            raise ValueError("need at least 2 distinct alpha_ids to compare")
        return out

    @field_validator("universe")
    @classmethod
    def _universe_known(cls, v: str) -> str:
        if v not in _BENCH_UNIVERSES:
            raise ValueError(
                f"unknown universe {v!r}; expected one of {sorted(_BENCH_UNIVERSES)}"
            )
        return v

    @field_validator("sort")
    @classmethod
    def _sort_known(cls, v: str) -> str:
        if v not in _VALID_SORTS:
            raise ValueError(f"unknown sort {v!r}; expected one of {sorted(_VALID_SORTS)}")
        return v

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Implement get_positions to call the broker positions API and return {"positions": [ ... normalized position dicts ... ]}
  2. Reinstall/refresh the installed plugin copy after editing
  3. Do not select this profile for position reads until implemented

Example fix

# before
def get_positions(*, credentials, config):
    raise NotImplementedError("Call the broker positions endpoint...")

# after
def get_positions(*, credentials, config):
    resp = broker_client(credentials).list_positions()
    return {"positions": [
        {"symbol": p["symbol"], "qty": float(p["qty"]), "market_value": float(p["market_value"])}
        for p in resp
    ]}
Defensive patterns

Strategy: try-catch

Type guard

def positions_implemented(adapter) -> bool:
    import inspect
    fn = getattr(adapter, "get_positions", None)
    return callable(fn) and "NotImplementedError" not in inspect.getsource(fn)

Try / catch

try:
    result = _local_plugin_call(profile, "get_positions", overrides)
except NotImplementedError:
    return {"positions": [], "unavailable": True}  # graceful degrade

Prevention

When it happens

Trigger: Calling get_positions (directly or via the trading service) on a scaffolded-but-unimplemented local connector; the stub raises because it contains no broker logic.

Common situations: Testing discovery/install flow with a stock scaffold; implemented account snapshot but left positions as the stub; copied an old scaffold missing the newer contract.

Related errors


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