{"record":{"id":"ae9adf7ad18b2fde","repo":"OpenBB-finance/OpenBB","slug":"unexpected-response-format-when-fetching-constrain","errorCode":null,"errorMessage":"Unexpected response format when fetching constraints {dataflow_id}: {e} -> {url}","messagePattern":"Unexpected response format when fetching constraints (.+?): (.+?) -> (.+?)","errorType":"exception","errorClass":"OpenBBError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/imf/openbb_imf/utils/metadata.py","lineNumber":746,"sourceCode":"        query_params.update(c_params)\n\n        query_params = {k: v for k, v in query_params.items() if v is not None}\n        url = (\n            base_url + \"?\" + \"&\".join(f\"{k}={v}\" for k, v in query_params.items())\n            if query_params\n            else base_url\n        )\n        json_response: dict = {}\n        try:\n            headers = {\n                \"Accept\": \"application/json\",\n                \"User-Agent\": \"Open Data Platform - IMF Metadata Utility\",\n            }\n            response = make_request(url, headers=headers)\n            response.raise_for_status()\n            json_response = response.json()\n        except json.JSONDecodeError as e:\n            raise OpenBBError(\n                f\"Unexpected response format when fetching constraints {dataflow_id}: {e}\"\n                + f\" -> {url}\"\n            ) from None\n        except RequestException as e:\n            raise OpenBBError(\n                f\"An error occurred while fetching constraints {dataflow_id}: {e} -> {url}\"\n            ) from None\n\n        extracted_values: dict = {}\n        json_data = json_response.get(\"data\", {})\n        data_constraints = json_data.get(\"dataConstraints\", [])\n\n        for constraint in data_constraints:\n            for region in constraint.get(\"cubeRegions\", []):\n                for kv in region.get(\"keyValues\", []):\n                    dim_id = kv.get(\"id\")\n                    if dim_id:\n                        if dim_id not in extracted_values:","sourceCodeStart":728,"sourceCodeEnd":764,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/imf/openbb_imf/utils/metadata.py#L728-L764","documentation":"Raised when the SDMX availability/constraints endpoint returns HTTP success or a response whose body is not valid JSON (response.json() raises json.JSONDecodeError). The message includes the JSON error and the exact URL queried. Typical shapes: an HTML error page served with 200, an empty body from a gateway, or an XML SDMX error delivered to a request that declared Accept: application/json.","triggerScenarios":"IMF API gateway briefly returning HTML maintenance pages; requesting a constraints key so long the server truncates it and responds with an HTML 414/400-style page; XML error envelopes on malformed keys; proxy/CDN interstitials.","commonSituations":"Very large indicator selections producing long availability URLs; transient gateway issues; corporate proxies injecting HTML; API contract changes after IMF portal updates.","solutions":["Retry after a short delay — transient gateway pages usually clear.","Reduce the size of the constraint key (fewer indicator codes per call) to avoid URL-length-triggered error pages; the module already limits keys to depth 0-1 codes for this reason.","If persistent, update openbb-imf (the endpoint or response shape may have changed) and inspect the URL from the message directly in a browser/curl to see what is actually returned."],"exampleFix":"# before\nconstraints = meta.fetch_dataflow_constraints('IMTS', key='A.US.TXG_FOB_USD+TXG_CIF_USD+...' )  # 50-code key -> long URL -> HTML error page\n\n# after (chunked keys)\nfor chunk in chunkify(indicator_codes, 5):\n    constraints = meta.fetch_dataflow_constraints('IMTS', key='.'.join(['A', 'US', '+'.join(chunk)]))","handlingStrategy":"retry","validationCode":"# keep constraint keys short to avoid URL-length error pages\nif len(key) > 1500:\n    raise ValueError('Constraint key too long; split indicator codes into smaller calls.')","typeGuard":null,"tryCatchPattern":"import asyncio\nfor attempt in range(3):\n    try:\n        constraints = meta.fetch_dataflow_constraints(df_id, **kwargs)\n        break\n    except OpenBBError as e:\n        if 'Unexpected response format' not in str(e) or attempt == 2:\n            raise\n        await asyncio.sleep(2 ** attempt)","preventionTips":["Chunk indicator codes so availability URLs stay short.","Treat non-JSON responses as transient first, structural second (after 2-3 retries, update openbb-imf).","Log the URL embedded in the message — it reproduces the failure directly in curl/a browser."],"tags":["network","imf","json","sdmx","constraints","retry"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}