{"record":{"id":"ac46155c67249a67","repo":"OpenBB-finance/OpenBB","slug":"failed-to-fetch-data-response-status-ac4615","errorCode":null,"errorMessage":"Failed to fetch data: {response.status}","messagePattern":"Failed to fetch data: (.+?)","errorType":"http","errorClass":"OpenBBError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/imf/openbb_imf/utils/port_watch_helpers.py","lineNumber":157,"sourceCode":"            if start_date is not None and end_date is not None\n            else (\n                CHOKEPOINTS_BASE_URL\n                + f\"where=portid%20%3D%20%27{chokepoint_id.upper()}%27&\"\n                + f\"outFields=*&orderByFields=date&returnZ=true&resultOffset={offset}&resultRecordCount=1000\"\n                + \"&maxRecordCountFactor=5&outSR=&f=json\"\n            )\n        )\n\n    offset: int = 0\n    output: dict = {}\n    url = get_chokepoints_url(offset)\n\n    async with await get_async_requests_session() as session:\n        async with await session.get(url) as response:\n            data: dict = {}\n\n            if response.status != 200:\n                raise OpenBBError(f\"Failed to fetch data: {response.status}\")\n            data = await response.json()\n\n        if \"features\" in data:\n            output = data.copy()\n\n        while data.get(\"exceededTransferLimit\") is True:\n            offset += len(data[\"features\"])\n            url = get_chokepoints_url(offset)\n\n            async with await session.get(url) as response:\n                data = {}\n                if response.status != 200:\n                    raise OpenBBError(f\"Failed to fetch data: {response.status}\")\n                data = await response.json()\n\n            if \"features\" in data:\n                output[\"features\"].extend(data[\"features\"])\n","sourceCodeStart":139,"sourceCodeEnd":175,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/imf/openbb_imf/utils/port_watch_helpers.py#L139-L175","documentation":"Raised during the first page of the Port Watch chokepoints fetch (ArcGIS hub feature service): the async HTTP status was not 200, and the helper converts it to an OpenBBError with the numeric status. Any 4xx/5xx (auth-less service, so typically 429/5xx/404 after endpoint changes) lands here.","triggerScenarios":"Calling get_chokepoints / the chokepoints listing function when the ArcGIS endpoint is degraded, rate-limiting (429), or the URL/dataset id changed (404).","commonSituations":"ArcGIS hub maintenance windows, heavy scraping triggering throttles, breaking changes to the dataset id baked into get_chokepoints_url.","solutions":["Retry with backoff — transient ArcGIS 5xx/429 responses usually clear within seconds to minutes.","Open the constructed URL (from get_chokepoints_url) in a browser/curl to check whether the dataset moved.","Check IMF Port Watch status pages for announced ArcGIS migrations."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"import requests\nok = requests.get(get_chokepoints_url(0), timeout=10).status_code == 200","typeGuard":null,"tryCatchPattern":"try:\n    pts = await get_chokepoints()\nexcept OpenBBError as e:\n    if 'Failed to fetch data:' in str(e):\n        raise Retryable(str(e)) from e  # transient ArcGIS status; backoff and retry\n    raise","preventionTips":["Wrap chokepoint fetches in exponential backoff (2-3 attempts).","Cache chokepoint metadata — it rarely changes."],"tags":["imf","port-watch","arcgis","http","chokepoints"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}