Skip to content

get_history_metadata() raises YFPricesMissingError for valid tickers when intraday data is unavailable #2745

Description

@ymyke

Describe bug

get_history_metadata() can raise YFPricesMissingError for valid, non-delisted tickers (e.g., ROG.SW) even after history() succeeds.

The method forces a second request (period="5d", interval="1h") to populate tradingPeriods in the metadata. For some tickers/exchanges, this intraday request returns no price data and raises YFPricesMissingError. The metadata — including currency, exchangeName, timezone, etc. — was already populated by the prior history() call, but the method refuses to return it.

Worse, the failing request can overwrite the already-populated _history_metadata with {} (line 224-225 of history.py), destroying cached metadata.

This is a regression from 0.2.x where get_history_metadata() returned whatever metadata was already cached without the tradingPeriods gate.

Related: #2344 fixed the inverse problem (metadata call corrupting history cache) but introduced this failure path.

Simple code that reproduces your problem

import yfinance as yf
yf.config.debug.hide_exceptions = False

ticker = yf.Ticker("ROG.SW")
df = ticker.history(start="2024-01-01")
print(f"history() OK: {len(df)} rows")

md = ticker.get_history_metadata()  # raises YFPricesMissingError

Root cause

In scrapers/history.py:

def get_history_metadata(self) -> dict:
    if self._history_metadata is None or 'tradingPeriods' not in self._history_metadata:
        self._get_history_cache(period="5d", interval="1h")  # <-- fails here

The or 'tradingPeriods' not in self._history_metadata clause forces a second intraday request even when metadata is already populated. If that request fails, the method raises instead of returning the metadata it already has.

Suggested fix

Two changes:

  1. Don't let the tradingPeriods fetch break the getter:
def get_history_metadata(self) -> dict:
    if self._history_metadata is None or 'tradingPeriods' not in self._history_metadata:
        try:
            self._get_history_cache(period="5d", interval="1h")
        except YFPricesMissingError:
            pass  # tradingPeriods is optional enrichment
    ...
  1. Don't overwrite good metadata with {} on failure (line ~224):
if data['chart']['result'] is not None:
    self._history_metadata = data["chart"]["result"][0]["meta"]
elif self._history_metadata is None:
    self._history_metadata = {}

yfinance version

Tested on 1.0 and 1.2.1 — both affected.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions