HKUDS/Vibe-Trading · error · AlpacaConfigError
feed must be 'iex' or 'sip'
Error message
feed must be 'iex' or 'sip'
What it means
Thrown by AlpacaConfig.from_mapping when the normalized 'feed' key is not 'iex' or 'sip' (default is 'iex'). The feed selects which market-data stream Alpaca serves; IEX is free/default while SIP requires a paid subscription, so unknown feeds are rejected at config-build time.
Source
Thrown at agent/src/trading/connectors/alpaca/sdk.py:96
"""
api_key: str = ""
secret_key: str = ""
profile: str = "paper"
feed: str = "iex"
timeout: float = 15.0
readonly: bool = True
@classmethod
def from_mapping(cls, data: Mapping[str, Any] | None = None) -> "AlpacaConfig":
"""Build a config from a JSON-like mapping, normalizing the profile."""
payload = dict(data or {})
profile = str(payload.get("profile") or "paper").strip().lower()
if profile not in PROFILE_ENVIRONMENTS:
raise AlpacaConfigError("profile must be 'paper', 'live-readonly' or 'live'")
feed = str(payload.get("feed") or "iex").strip().lower()
if feed not in ("iex", "sip"):
raise AlpacaConfigError("feed must be 'iex' or 'sip'")
return cls(
api_key=str(payload.get("api_key") or "").strip(),
secret_key=str(payload.get("secret_key") or "").strip(),
profile=profile,
feed=feed,
timeout=float(payload.get("timeout") or 15.0),
readonly=bool(payload.get("readonly", True)),
)
def with_overrides(
self,
*,
api_key: str | None = None,
secret_key: str | None = None,
profile: str | None = None,
feed: str | None = None,
) -> "AlpacaConfig":
"""Return a copy with CLI/tool overrides applied."""View on GitHub (pinned to 80ffdda44c)
Solutions
- Set feed to 'iex' or remove it to use the free default
- Set feed to 'sip' only if your Alpaca subscription includes SIP data
- Double-check spelling — values are lowercased and trimmed, but must match exactly
- Re-run after fixing the JSON config file that load_config reads
Example fix
// before
{"profile": "paper", "feed": "nasdaq"}
// after
{"profile": "paper", "feed": "iex"} Defensive patterns
Strategy: validation
Validate before calling
VALID_FEEDS = {"iex", "sip"}
feed = str(cfg.get("feed") or "iex").strip().lower()
if feed not in VALID_FEEDS:
raise ValueError(f"unknown feed {feed!r}; expected 'iex' or 'sip'") Type guard
def is_valid_alpaca_feed(value: object) -> bool:
return isinstance(value, str) and value.strip().lower() in {"iex", "sip"} Try / catch
try:
config = AlpacaConfig.from_mapping(data)
except AlpacaConfigError as exc:
if "feed must be" in str(exc):
data["feed"] = "iex"
config = AlpacaConfig.from_mapping(data)
else:
raise Prevention
- Default to omitting feed (iex) unless you have a SIP subscription
- Restrict feed to a dropdown in settings UIs
- Add a config-file lint step that runs from_mapping on load in CI
When it happens
Trigger: Passing a mapping with feed set to e.g. 'SIP ' works (lowercased/trimmed) but 'sip-pro', 'otc', 'cts', or 'full' raises. Hit via load_config from a JSON file, build_config overrides, or with_overrides.
Common situations: Copying feed names from other broker APIs; assuming a paid-tier name like 'nasdaq-totalview' is supported; typos like 'ix' or 'siep'; stale docs from an older SDK version listing other feeds.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- profile must be 'paper', 'live-readonly' or 'live'
- invalid Alpaca config at {path}: {exc}
- each local connection must be an object
- invalid local connection id: {connection_id or '?'}
- connection profile is not eligible for read-only portfolios:
AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28).
Data as JSON: /api/errors/a51a74b138c49c86.
Report an issue: GitHub.