OpenBB-finance/OpenBB · error · KeyError

Dataflow '{dataflow_id}' not found. Available dataflows: {li

Error message

Dataflow '{dataflow_id}' not found. Available dataflows: {list(self._builder.metadata.dataflows.keys())}

What it means

ImfParamsBuilder raises KeyError in __init__ when the requested dataflow_id is not present in the IMF SDMX metadata's dataflows dictionary (fetched/loaded by ImfQueryBuilder). The message lists all known dataflow IDs to help correction.

Source

Thrown at openbb_platform/providers/imf/openbb_imf/utils/progressive_helper.py:23

from openbb_imf.utils.query_builder import ImfQueryBuilder


class ImfParamsBuilder:
    """A helper class to build IMF queries progressively by making sequential dimension selections,
    for each dimension of a dataflow, filtering the available options at each step based on previous selections.
    """

    def __init__(self, dataflow_id: str):
        """Initialize the ImfParamsBuilder object.

        Parameters
        ----------
        dataflow_id : str
            The ID of the dataflow to build a query for.
        """
        self._builder = ImfQueryBuilder()
        if dataflow_id not in self._builder.metadata.dataflows:
            raise KeyError(
                f"Dataflow '{dataflow_id}' not found."
                f" Available dataflows: {list(self._builder.metadata.dataflows.keys())}"
            )

        self.dataflow_id = dataflow_id
        self.dsd = self._get_dsd()
        self._dimensions = self._get_dimensions_in_order()
        self.current_dimension = self._dimensions[0] if self._dimensions else None
        self._selections: dict = {dim: None for dim in self._dimensions}
        self._last_constraints_response: dict = {}

    def _get_dsd(self):
        """Get the Data Structure Definition (DSD) for the current dataflow."""
        df_obj = self._builder.metadata.dataflows[self.dataflow_id]
        dsd_id = df_obj.get("structureRef", {}).get("id")
        return self._builder.metadata.datastructures.get(dsd_id, {})

    def _get_dimensions_in_order(self) -> list[str]:

View on GitHub (pinned to 3e071fcc2c)

Solutions

  1. Instantiate ImfQueryBuilder().metadata.dataflows and pick the exact ID from the message's available list.
  2. Refresh/clear cached IMF metadata so newly published dataflows appear.
  3. Upgrade the openbb-imf provider if the dataflow was added in a newer release.
  4. Guard interactive flows by validating the ID against metadata before constructing the builder.

Example fix

# before
builder = ImfParamsBuilder(dataflow_id='BOP_AGGS')  # KeyError

# after
from openbb_imf.utils.query_builder import ImfQueryBuilder
valid = ImfQueryBuilder().metadata.dataflows
assert 'BOP' in valid, f'pick from {list(valid)}'
builder = ImfParamsBuilder(dataflow_id='BOP')
Defensive patterns

Strategy: validation

Validate before calling

from openbb_imf.utils.query_builder import ImfQueryBuilder

def is_valid_dataflow(dataflow_id: str) -> bool:
    return dataflow_id in ImfQueryBuilder().metadata.dataflows

assert is_valid_dataflow('BOP')

Type guard

def is_valid_dataflow(dataflow_id: str, metadata) -> TypeGuard[str]:
    return isinstance(dataflow_id, str) and dataflow_id in metadata.dataflows

Try / catch

try:
    builder = ImfParamsBuilder(dataflow_id)
except KeyError as e:
    if 'not found' in str(e):
        suggest = difflib.get_close_matches(dataflow_id, list(builder_md.dataflows), n=1)
        raise ValueError(f'Unknown dataflow; did you mean {suggest}?') from e
    raise

Prevention

When it happens

Trigger: Constructing ImfParamsBuilder('PGF') style calls with a wrong, renamed, or not-yet-loaded dataflow ID; also case or spelling mistakes (e.g. 'BOP' vs 'BOP_X').

Common situations: Using a dataflow ID from an outdated IMF page or older openbb version, stale cached metadata after IMF adds dataflows, or scripts with hardcoded IDs that IMF has retired.

Related errors


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