{"record":{"id":"3492580a8aeb5657","repo":"OpenBB-finance/OpenBB","slug":"json-response-error","errorCode":null,"errorMessage":"json_response[\"error\"]","messagePattern":"json_response\\[\"error\"\\]","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/deribit/openbb_deribit/utils/helpers.py","lineNumber":286,"sourceCode":"        for start, end in windows:\n            start_timestamp = int(start.timestamp() * 1000)\n            end_timestamp = int(end.timestamp() * 1000)\n            url = (\n                \"https://www.deribit.com/api/v2/public/get_tradingview_chart_data?\"\n                f\"instrument_name={symbol}&start_timestamp={start_timestamp}&\"\n                f\"end_timestamp={end_timestamp}&resolution={interval}\"\n            )\n            urls.append(url)\n\n        return urls\n\n    results: list = []\n\n    async def get_one(url):\n        \"\"\"Get data from one url.\"\"\"\n        json_response = await amake_request(url)\n        if json_response.get(\"error\"):  # type: ignore[union-attr]\n            raise ValueError(json_response[\"error\"])  # type: ignore[call-overload]\n        if json_response.get(\"result\"):  # type: ignore[union-attr]\n            result = json_response[\"result\"]  # type: ignore[call-overload]\n            df = DataFrame(result)\n            df = (\n                df.drop(columns=[\"status\"])\n                .rename(columns={\"ticks\": \"date\", \"cost\": \"volume_notional\"})\n                .convert_dtypes()\n            )\n            df[\"date\"] = to_datetime(df.date, unit=\"ms\", origin=\"unix\", utc=True)\n            if interval == \"1D\":\n                df.date = df.date.dt.date\n            df[\"symbol\"] = symbol\n            results.extend(\n                df[\n                    [\n                        \"date\",\n                        \"symbol\",\n                        \"open\",","sourceCodeStart":268,"sourceCodeEnd":304,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/deribit/openbb_deribit/utils/helpers.py#L268-L304","documentation":"ValueError raised inside get_ohlc_data's per-URL fetcher when a Deribit tradingview-style chart response contains a non-null 'error' envelope (HTTP 200 with in-band error). Typical payloads include invalid-resolution or out-of-range errors for a generated windowed URL. Each URL covers up to 5000 candles of the requested range.","triggerScenarios":"An interval Deribit's charting endpoint rejects for that instrument, a window whose start/end timestamps fall outside the instrument's data availability, or too-large symbol histories chunked into a window the API refuses. Because the fetcher is per-window, one bad window aborts that symbol's whole fetch after some results were already gathered.","commonSituations":"Requesting 1m candles over multi-year ranges (windowed URLs may still hit API limits), using intervals not in INTERVAL_MAP verbatim, or date ranges preceding instrument creation.","solutions":["Use a supported interval string exactly as documented (1m..12h, 1d); INTERVAL_MAP translates them but exotic values pass through and can be rejected.","Clamp start_date to the instrument's creation date (get the creation_timestamp from get_instruments).","Split very long ranges into smaller requests to avoid per-window API refusals.","Read the embedded Deribit error dict — its 'message' names the exact reason (e.g. resolution not available)."],"exampleFix":"# before\ndata = await get_ohlc_data(\"BTC-PERPETUAL\", interval=\"90m\", start_date=\"2016-01-01\", end_date=\"2026-01-01\")\n\n# after\ndata = await get_ohlc_data(\"BTC-PERPETUAL\", interval=\"1h\", start_date=\"2024-01-01\", end_date=\"2024-06-01\")","handlingStrategy":"validation","validationCode":"VALID_INTERVALS = {\"1m\", \"3m\", \"5m\", \"10m\", \"15m\", \"30m\", \"1h\", \"2h\", \"3h\", \"6h\", \"12h\", \"1d\"}\nassert interval in VALID_INTERVALS, f\"interval must be one of {sorted(VALID_INTERVALS)}\"\n# also clamp start to the instrument's creation date\ncreated_ms = {d[\"instrument_name\"]: d[\"creation_timestamp\"] for d in asyncio.run(get_instruments(\"all\", None))}[symbol]\nstart = max(start, created_ms / 1000)","typeGuard":"from typing import Literal, TypeGuard\nDeribitInterval = Literal[\"1m\", \"3m\", \"5m\", \"10m\", \"15m\", \"30m\", \"1h\", \"2h\", \"3h\", \"6h\", \"12h\", \"1d\"]\n\ndef is_deribit_interval(s: str) -> TypeGuard[DeribitInterval]:\n    return s in {\"1m\", \"3m\", \"5m\", \"10m\", \"15m\", \"30m\", \"1h\", \"2h\", \"3h\", \"6h\", \"12h\", \"1d\"}","tryCatchPattern":"try:\n    candles = await get_ohlc_data(symbol, interval, start, end)\nexcept ValueError as e:\n    err = e.args[0] if e.args else {}\n    msg = err.get(\"message\", str(err)) if isinstance(err, dict) else str(err)\n    if \"resolution\" in msg.lower():\n        candles = await get_ohlc_data(symbol, \"1h\", start, end)  # fall back to canonical interval\n    else:\n        raise","preventionTips":["Use canonical interval strings; don't pass raw minute counts or exotic units.","Clamp start_date to instrument creation and keep ranges modest (the fetcher chunks at 5000 candles per window).","Parse the embedded Deribit error dict — its 'message' names the exact refusal reason."],"tags":["deribit","ohlc","api-error","interval","date-range"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}