{"record":{"id":"12a15e33603abc71","repo":"OpenBB-finance/OpenBB","slug":"unexpected-data-format-expected-ratings-key-go","errorCode":null,"errorMessage":"Unexpected data format. Expected 'ratings' key, got: {list(data.keys())}","messagePattern":"Unexpected data format\\. Expected 'ratings' key, got: (.+?)","errorType":"exception","errorClass":"OpenBBError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/benzinga/openbb_benzinga/models/price_target.py","lineNumber":297,"sourceCode":"        query: BenzingaPriceTargetQueryParams,\n        credentials: dict[str, str] | None,\n        **kwargs: Any,\n    ) -> list[dict]:\n        \"\"\"Return the raw data from the Benzinga endpoint.\"\"\"\n        # pylint: disable=import-outside-toplevel\n        from openbb_benzinga.utils.helpers import response_callback\n        from openbb_core.provider.utils.helpers import amake_request, get_querystring\n\n        token = credentials.get(\"benzinga_api_key\") if credentials else \"\"\n        base_url = \"https://api.benzinga.com/api/v2.1/calendar/ratings\"\n        query.limit = query.limit or 200\n        querystring = get_querystring(query.model_dump(by_alias=True), [])\n\n        url = f\"{base_url}?{querystring}&token={token}\"\n        data = await amake_request(url, response_callback=response_callback, **kwargs)\n\n        if isinstance(data, dict) and \"ratings\" not in data:\n            raise OpenBBError(\n                f\"Unexpected data format. Expected 'ratings' key, got: {list(data.keys())}\"\n            )\n        if not isinstance(data, dict):\n            raise OpenBBError(\n                f\"Unexpected data format. Expected dict, got: {type(data)}\"\n            )\n        if isinstance(data, dict) and not data.get(\"ratings\"):\n            raise EmptyDataError(\"No ratings data returned.\")\n\n        return data[\"ratings\"]\n\n    @staticmethod\n    def transform_data(\n        query: BenzingaPriceTargetQueryParams,\n        data: list[dict],\n        **kwargs: Any,\n    ) -> list[BenzingaPriceTargetData]:\n        \"\"\"Return the transformed data.\"\"\"","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/benzinga/openbb_benzinga/models/price_target.py#L279-L315","documentation":"BenzingaPriceTargetFetcher.a_fetch_data (price_target.py:297) validates the shape of Benzinga's /calendar/ratings payload: a dict that does not contain a 'ratings' key raises OpenBBError(\"Unexpected data format. Expected 'ratings' key, got: {list(data.keys())}\"). The endpoint answered 200 with JSON, but the body is not the expected wrapper — typically an error/limit object or a schema revision.","triggerScenarios":"Benzinga returns {\"error\": ...}, an auth notice, or renames/adds wrapper keys, so 'ratings' is absent from an otherwise valid dict.","commonSituations":"Invalid/expired API key, monthly-call quota exceeded (AV-style message bodies), or an API version change after openbb-benzinga was pinned.","solutions":["Read list(data.keys()) from the message to identify the actual body (look for 'error'/'message').","Refresh the benzinga_api_key credential and confirm quota status in the Benzinga console.","Upgrade openbb-benzinga to pick up current schema handling.","Handle OpenBBError distinctly from EmptyDataError so auth/schema issues surface instead of masquerading as no-data."],"exampleFix":"# before\ndata = await amake_request(url, response_callback=response_callback)\n# OpenBBError: Unexpected data format. Expected 'ratings' key, got: ['message']\n\n# after\nif isinstance(data, dict) and \"ratings\" not in data:\n    msg = data.get(\"message\") or data.get(\"error\") or list(data.keys())\n    raise OpenBBError(f\"Benzinga price-target endpoint replied: {msg}\")","handlingStrategy":"try-catch","validationCode":"# Pre-flight: confirm key works and payload shape is current\nprobe = await amake_request(base_url + \"?limit=1&token=\" + token, response_callback=response_callback)\nif not (isinstance(probe, dict) and \"ratings\" in probe):\n    raise RuntimeError(f\"Benzinga contract changed or auth failed: {list(probe.keys()) if isinstance(probe, dict) else type(probe)}\")","typeGuard":"def is_ratings_payload(data) -> bool:\n    return isinstance(data, dict) and \"ratings\" in data","tryCatchPattern":"from openbb_core.app.model.abstract.error import OpenBBError\ntry:\n    rows = await fetcher.a_fetch_data(query, credentials)\nexcept OpenBBError as e:\n    if \"Expected 'ratings' key\" in str(e):\n        # inspect reported keys; typically auth/quota or schema revision\n        logger.error(\"Benzinga price-target payload unexpected: %s\", e)\n    raise","preventionTips":["Monitor Benzinga quota and key expiry in dashboards.","Pin openbb-benzinga to a release matched to the API, and upgrade deliberately.","Don't conflate OpenBBError with EmptyDataError in handlers."],"tags":["python","openbb","benzinga","provider","schema"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}