OpenBB-finance/OpenBB · error · ValueError

json_response["error"]

Error message

json_response["error"]

What it means

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.

Source

Thrown at openbb_platform/providers/deribit/openbb_deribit/utils/helpers.py:286

        for start, end in windows:
            start_timestamp = int(start.timestamp() * 1000)
            end_timestamp = int(end.timestamp() * 1000)
            url = (
                "https://www.deribit.com/api/v2/public/get_tradingview_chart_data?"
                f"instrument_name={symbol}&start_timestamp={start_timestamp}&"
                f"end_timestamp={end_timestamp}&resolution={interval}"
            )
            urls.append(url)

        return urls

    results: list = []

    async def get_one(url):
        """Get data from one url."""
        json_response = await amake_request(url)
        if json_response.get("error"):  # type: ignore[union-attr]
            raise ValueError(json_response["error"])  # type: ignore[call-overload]
        if json_response.get("result"):  # type: ignore[union-attr]
            result = json_response["result"]  # type: ignore[call-overload]
            df = DataFrame(result)
            df = (
                df.drop(columns=["status"])
                .rename(columns={"ticks": "date", "cost": "volume_notional"})
                .convert_dtypes()
            )
            df["date"] = to_datetime(df.date, unit="ms", origin="unix", utc=True)
            if interval == "1D":
                df.date = df.date.dt.date
            df["symbol"] = symbol
            results.extend(
                df[
                    [
                        "date",
                        "symbol",
                        "open",

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Use a supported interval string exactly as documented (1m..12h, 1d); INTERVAL_MAP translates them but exotic values pass through and can be rejected.
  2. Clamp start_date to the instrument's creation date (get the creation_timestamp from get_instruments).
  3. Split very long ranges into smaller requests to avoid per-window API refusals.
  4. Read the embedded Deribit error dict — its 'message' names the exact reason (e.g. resolution not available).

Example fix

# before
data = await get_ohlc_data("BTC-PERPETUAL", interval="90m", start_date="2016-01-01", end_date="2026-01-01")

# after
data = await get_ohlc_data("BTC-PERPETUAL", interval="1h", start_date="2024-01-01", end_date="2024-06-01")
Defensive patterns

Strategy: validation

Validate before calling

VALID_INTERVALS = {"1m", "3m", "5m", "10m", "15m", "30m", "1h", "2h", "3h", "6h", "12h", "1d"}
assert interval in VALID_INTERVALS, f"interval must be one of {sorted(VALID_INTERVALS)}"
# also clamp start to the instrument's creation date
created_ms = {d["instrument_name"]: d["creation_timestamp"] for d in asyncio.run(get_instruments("all", None))}[symbol]
start = max(start, created_ms / 1000)

Type guard

from typing import Literal, TypeGuard
DeribitInterval = Literal["1m", "3m", "5m", "10m", "15m", "30m", "1h", "2h", "3h", "6h", "12h", "1d"]

def is_deribit_interval(s: str) -> TypeGuard[DeribitInterval]:
    return s in {"1m", "3m", "5m", "10m", "15m", "30m", "1h", "2h", "3h", "6h", "12h", "1d"}

Try / catch

try:
    candles = await get_ohlc_data(symbol, interval, start, end)
except ValueError as e:
    err = e.args[0] if e.args else {}
    msg = err.get("message", str(err)) if isinstance(err, dict) else str(err)
    if "resolution" in msg.lower():
        candles = await get_ohlc_data(symbol, "1h", start, end)  # fall back to canonical interval
    else:
        raise

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of OpenBB-finance/OpenBB@3e071fcc2c (2026-08-14). Data as JSON: /api/errors/3492580a8aeb5657. Report an issue: GitHub.