{"record":{"id":"a6c947c492ad9576","repo":"TauricResearch/TradingAgents","slug":"no-rows-between-start-date-and-end-date","errorCode":null,"errorMessage":"no rows between {start_date} and {end_date}","messagePattern":"no rows between (.+?) and (.+?)","errorType":"exception","errorClass":"NoMarketDataError","httpStatus":null,"severity":"error","filePath":"tradingagents/dataflows/y_finance.py","lineNumber":41,"sourceCode":"\n    datetime.strptime(start_date, \"%Y-%m-%d\")\n    end_dt = datetime.strptime(end_date, \"%Y-%m-%d\")\n\n    # Resolve broker/forex symbols to Yahoo's convention (XAUUSD+ -> GC=F).\n    canonical = normalize_symbol(symbol)\n    ticker = yf.Ticker(canonical)\n\n    # yfinance treats ``end`` as EXCLUSIVE, so it would drop the requested\n    # end_date row (and the current day when end_date is today). Request one day\n    # past end_date so the requested range is actually inclusive (#986/#987).\n    end_inclusive = (end_dt + relativedelta(days=1)).strftime(\"%Y-%m-%d\")\n    data = yf_retry(lambda: ticker.history(start=start_date, end=end_inclusive))\n\n    # Empty result means the symbol is unknown/delisted. Raise a typed error\n    # instead of returning prose: the routing layer turns it into a single\n    # unambiguous \"no data\" signal so the agent never fabricates a price.\n    if data.empty:\n        raise NoMarketDataError(\n            symbol, canonical, f\"no rows between {start_date} and {end_date}\"\n        )\n\n    # Remove timezone info from index for cleaner output\n    if data.index.tz is not None:\n        data.index = data.index.tz_localize(None)\n\n    # Reject a stale frame (e.g. a year-old partial response) before it is\n    # formatted into the report. Raises NoMarketDataError, which the router\n    # turns into one clear unavailable signal (#1021).\n    _assert_ohlcv_not_stale(data, end_date, symbol, canonical)\n\n    # Round numerical values to 2 decimal places for cleaner display\n    numeric_columns = [\"Open\", \"High\", \"Low\", \"Close\", \"Adj Close\"]\n    for col in numeric_columns:\n        if col in data.columns:\n            data[col] = data[col].round(2)\n","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/TauricResearch/TradingAgents/blob/a33fd4c0f134485a43553a2c23a63cb14adbd88f/tradingagents/dataflows/y_finance.py#L23-L59","documentation":"NoMarketDataError raised by get_YFinData in tradingagents/dataflows/y_finance.py when yfinance returns an empty history frame for the requested start/end range. An empty frame almost always means the symbol is unknown, delisted, or has no trading rows in the window. The routing layer converts this typed error into a single unambiguous 'no data' signal so downstream agents never fabricate prices.","triggerScenarios":"Calling get_YFinData(symbol, start_date, end_date) with an unrecognized/delisted ticker (e.g. 'FOOBAR'), a symbol with no trading days inside [start_date, end_date], or a date range entirely in the future. yf.Ticker(...).history(...) returns an empty DataFrame and the check raises.","commonSituations":"Typo'd tickers, delisted symbols, requesting a window before the IPO date, weekend/holiday-only windows, or Yahoo Finance temporarily returning empty payloads for valid symbols.","solutions":["Verify the ticker exists on Yahoo Finance (e.g. open finance.yahoo.com or call yf.Ticker(sym).info) before running the pipeline.","Widen the date range or ensure it contains at least one trading day for the symbol's exchange.","Catch NoMarketDataError at the orchestration layer and report 'market data unavailable' rather than retrying with the same inputs.","If Yahoo is intermittently empty, retry once after a short delay before giving up."],"exampleFix":"# before\ndata = get_YFinData(start_date, end_date, 'FOOBAR')\n\n# after\nfrom tradingagents.dataflows.errors import NoMarketDataError\ntry:\n    data = get_YFinData(start_date, end_date, 'FOOBAR')\nexcept NoMarketDataError:\n    data = None  # handle unavailable symbol explicitly","handlingStrategy":"try-catch","validationCode":"import yfinance as yf\n\ndef symbol_has_history(symbol: str, start: str, end: str) -> bool:\n    hist = yf.Ticker(symbol).history(start=start, end=end)\n    return not hist.empty","typeGuard":null,"tryCatchPattern":"from tradingagents.dataflows.errors import NoMarketDataError\n\ntry:\n    data = get_YFin_data_window(start_date, end_date, symbol)\nexcept NoMarketDataError as e:\n    logger.warning('no market data for %s: %s', symbol, e)\n    return None  # or report 'unavailable' upstream; do not retry same inputs","preventionTips":["Pre-screen tickers against a known-good universe before running the pipeline.","Keep NoMarketDataError handling in one orchestration layer so every data call is covered.","Treat empty windows (holidays/weekends) as config bugs: assert the range contains a trading day."],"tags":["market-data","yfinance","empty-response","ticker"],"backgroundTag":null,"analyzedSha":"a33fd4c0f134485a43553a2c23a63cb14adbd88f","analyzedAt":"2026-08-14T19:45:16.920Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}