{"record":{"id":"fab1a2f2cec5f62f","repo":"HKUDS/Vibe-Trading","slug":"profile-must-be-paper-live-readonly-or-live","errorCode":null,"errorMessage":"profile must be 'paper', 'live-readonly' or 'live'","messagePattern":"profile must be 'paper', 'live-readonly' or 'live'","errorType":"validation","errorClass":"AlpacaConfigError","httpStatus":null,"severity":"error","filePath":"agent/src/trading/connectors/alpaca/sdk.py","lineNumber":93,"sourceCode":"        feed: Market-data feed, ``iex`` (free) or ``sip`` (paid).\n        timeout: Network timeout in seconds.\n        readonly: Always true for this layer; order methods are not exposed.\n    \"\"\"\n\n    api_key: str = \"\"\n    secret_key: str = \"\"\n    profile: str = \"paper\"\n    feed: str = \"iex\"\n    timeout: float = 15.0\n    readonly: bool = True\n\n    @classmethod\n    def from_mapping(cls, data: Mapping[str, Any] | None = None) -> \"AlpacaConfig\":\n        \"\"\"Build a config from a JSON-like mapping, normalizing the profile.\"\"\"\n        payload = dict(data or {})\n        profile = str(payload.get(\"profile\") or \"paper\").strip().lower()\n        if profile not in PROFILE_ENVIRONMENTS:\n            raise AlpacaConfigError(\"profile must be 'paper', 'live-readonly' or 'live'\")\n        feed = str(payload.get(\"feed\") or \"iex\").strip().lower()\n        if feed not in (\"iex\", \"sip\"):\n            raise AlpacaConfigError(\"feed must be 'iex' or 'sip'\")\n        return cls(\n            api_key=str(payload.get(\"api_key\") or \"\").strip(),\n            secret_key=str(payload.get(\"secret_key\") or \"\").strip(),\n            profile=profile,\n            feed=feed,\n            timeout=float(payload.get(\"timeout\") or 15.0),\n            readonly=bool(payload.get(\"readonly\", True)),\n        )\n\n    def with_overrides(\n        self,\n        *,\n        api_key: str | None = None,\n        secret_key: str | None = None,\n        profile: str | None = None,","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/trading/connectors/alpaca/sdk.py#L75-L111","documentation":"Thrown by AlpacaConfig.from_mapping when the normalized 'profile' key is not one of the allowed PROFILE_ENVIRONMENTS ('paper', 'live-readonly', 'live'). The profile decides which Alpaca environment/endpoints are used, so an unrecognized value fails fast instead of defaulting to real-money trading.","triggerScenarios":"Passing a mapping (from JSON config, build_config overrides, or with_overrides) whose profile is e.g. 'production', 'LIVE!' after lowercasing still mismatches, 'live_readonly' (underscore typo), or an empty string is fine (defaults to paper) — the error needs a present-but-unknown value.","commonSituations":"Typos in the alpaca config file (live_ro, LIVE_READONLY); config shared from another SDK that uses 'production'/'sandbox'; old config files from a version before 'live-readonly' existed; env-var interpolation writing garbage into the profile field.","solutions":["Set profile to exactly 'paper', 'live-readonly', or 'live' (lowercase, hyphenated)","If you intended paper trading, omit the key entirely — it defaults to 'paper'","Check for stray whitespace/quotes in the JSON value (they survive strip but mismatched names do not)","Upgrade to the current agent version if your config uses an older profile vocabulary"],"exampleFix":"// before\n{\"profile\": \"live_ro\", \"api_key\": \"...\", \"secret_key\": \"...\"}\n\n// after\n{\"profile\": \"live-readonly\", \"api_key\": \"...\", \"secret_key\": \"...\"}","handlingStrategy":"validation","validationCode":"VALID_PROFILES = {\"paper\", \"live-readonly\", \"live\"}\nprofile = str(cfg.get(\"profile\") or \"paper\").strip().lower()\nif profile not in VALID_PROFILES:\n    raise ValueError(f\"unknown profile {profile!r}; expected one of {sorted(VALID_PROFILES)}\")","typeGuard":"def is_valid_alpaca_profile(value: object) -> bool:\n    return (\n        isinstance(value, str)\n        and value.strip().lower() in {\"paper\", \"live-readonly\", \"live\"}\n    )","tryCatchPattern":"try:\n    config = AlpacaConfig.from_mapping(data)\nexcept AlpacaConfigError as exc:\n    if \"profile must be\" in str(exc):\n        data[\"profile\"] = \"paper\"\n        config = AlpacaConfig.from_mapping(data)\n    else:\n        raise","preventionTips":["Offer a fixed dropdown (paper/live-readonly/live) instead of free-text profile input","Validate config files in CI with from_mapping as a smoke test","Document that profile is lowercased hyphenated, not underscored"],"tags":["python","alpaca","configuration","enum-validation"],"backgroundTag":"invalid-config-value","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}