HKUDS/Vibe-Trading · error · ValueError

unknown security_type {self.security_type!r}; expected one o

Error message

unknown security_type {self.security_type!r}; expected one of: {valid}

What it means

Security.__post_init__ coerces security_type through the SecurityType enum; unknown strings raise ValueError with the list of valid values. The match is exact against enum member values.

Source

Thrown at agent/src/entities/models.py:261

    def __post_init__(self) -> None:
        """Validate the base fields and coerce ``security_type``.

        Raises:
            ValueError: If ``security_type`` is not a known member.
        """
        super().__post_init__()
        object.__setattr__(self, "symbol", self.symbol.strip() if self.symbol else "")
        object.__setattr__(
            self, "exchange", self.exchange.strip() if self.exchange else ""
        )
        try:
            object.__setattr__(
                self, "security_type", SecurityType(self.security_type)
            )
        except ValueError as exc:
            valid = ", ".join(member.value for member in SecurityType)
            raise ValueError(
                f"unknown security_type {self.security_type!r}; "
                f"expected one of: {valid}"
            ) from exc


@dataclass(frozen=True)
class Fund(Instrument):
    """A pooled vehicle whose economics are calls, distributions, and NAV marks.

    This is the archetypal instrument that cannot be expressed as a daily bar:
    a closed-end fund has no price, only an irregular cash-flow stream and a
    periodic valuation.

    Attributes:
        vintage_year: Year the fund began investing, when known.
        structure: Capital structure; see ``FundStructure``.
        strategy: Free-form strategy label, e.g. ``"buyout"``.
        commitment: Total capital committed by the holder, in ``currency``.

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Pass an exact SecurityType member or its .value
  2. Build an alias/normalization map (strip, upper/lower, vendor codes) before constructing Security objects
  3. When the type is genuinely new, extend the SecurityType enum rather than bypassing validation

Example fix

# before
Security(instrument_id='a', security_type='common stock')

# after
Security(instrument_id='a', security_type=SecurityType.COMMON_STOCK.value)
Defensive patterns

Strategy: validation

Validate before calling

from agent.src.entities.models import SecurityType
valid = {m.value for m in SecurityType}
st = row['security_type'].strip()
if st not in valid:
    st = ALIAS_MAP.get(st.lower(), st)
assert st in valid, f"bad security_type {st!r}"

Type guard

from agent.src.entities.models import SecurityType

def is_valid_security_type(v: str) -> bool:
    try:
        SecurityType(v)
        return True
    except ValueError:
        return False

Try / catch

try:
    s = Security(instrument_id=iid, security_type=st, ...)
except ValueError as exc:
    if 'unknown security_type' in str(exc):
        log.warning('quarantining row with bad security_type %r', st)
        continue
    raise

Prevention

When it happens

Trigger: Security(instrument_id='x', security_type='Common Stock') with case mismatch, trailing whitespace, or a label not in SecurityType (e.g. 'etf' when only 'ETF' or 'fund' are defined).

Common situations: Mapping vendor security type codes (e.g. 'CS', 'EQ') directly to the field without a translation table; free-text type columns in reference data; enum members added/renamed across versions while persisted records keep old labels.

Related errors


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