{"record":{"id":"a16829bd5ad4860b","repo":"TauricResearch/TradingAgents","slug":"no-fundamental-fields-returned","errorCode":null,"errorMessage":"no fundamental fields returned","messagePattern":"no fundamental fields returned","errorType":"exception","errorClass":"NoMarketDataError","httpStatus":null,"severity":"error","filePath":"tradingagents/dataflows/y_finance.py","lineNumber":328,"sourceCode":"            (\"Return on Equity\", info.get(\"returnOnEquity\")),\n            (\"Return on Assets\", info.get(\"returnOnAssets\")),\n            (\"Debt to Equity\", info.get(\"debtToEquity\")),\n            (\"Current Ratio\", info.get(\"currentRatio\")),\n            (\"Book Value\", info.get(\"bookValue\")),\n            (\"Free Cash Flow\", info.get(\"freeCashflow\")),\n        ]\n\n        lines = []\n        for label, value in fields:\n            if value is not None:\n                lines.append(f\"{label}: {value}\")\n\n        # yfinance returns a stub dict (e.g. {\"trailingPegRatio\": None}) for\n        # unknown symbols, so `info` is truthy but every field is empty. Treat\n        # \"no usable fields\" as no data rather than emitting a bare header the\n        # agent might fabricate around.\n        if not lines:\n            raise NoMarketDataError(ticker, canonical, \"no fundamental fields returned\")\n\n        header = f\"# Company Fundamentals for {canonical}\\n\"\n        header += f\"# Data retrieved on: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\\n\\n\"\n\n        return header + \"\\n\".join(lines)\n\n    except NoMarketDataError:\n        raise\n    except Exception as e:\n        return f\"Error retrieving fundamentals for {ticker}: {str(e)}\"\n\n\ndef get_balance_sheet(\n    ticker: Annotated[str, \"ticker symbol of the company\"],\n    freq: Annotated[str, \"frequency of data: 'annual' or 'quarterly'\"] = \"quarterly\",\n    curr_date: Annotated[str, \"current date in YYYY-MM-DD format\"] = None\n):\n    \"\"\"Get balance sheet data from yfinance.\"\"\"","sourceCodeStart":310,"sourceCodeEnd":346,"githubUrl":"https://github.com/TauricResearch/TradingAgents/blob/a33fd4c0f134485a43553a2c23a63cb14adbd88f/tradingagents/dataflows/y_finance.py#L310-L346","documentation":"NoMarketDataError raised by get_fundamentals when ticker.info is truthy but every interesting field (Name, Sector, PE, EPS, ...) is None. yfinance returns a stub dict like {'trailingPegRatio': None} for unknown symbols, so a bare truthiness check on info is insufficient. Treating 'no usable fields' as no data prevents emitting a bare header the agent might fabricate around.","triggerScenarios":"Calling get_fundamentals on a symbol where Yahoo returns a stub info dict — all mapped fields are None, `lines` stays empty, and the check raises. Distinct from error 23, which fires when info itself is empty.","commonSituations":"Unknown-but-not-404 symbols (mutual funds, dead tickers, some international listings) where Yahoo returns a skeleton profile; API version changes that rename info keys so all gets return None.","solutions":["Validate the symbol has a real profile first (e.g. check that yf.Ticker(sym).info contains 'longName' or 'sector').","Handle NoMarketDataError at the call site and mark fundamentals as unavailable instead of retrying.","Upgrade yfinance if field-name drift is suspected — keys like trailingPE/marketCap occasionally change."],"exampleFix":"# before\nreport = get_fundamentals('ZZZZ.ZY')\n\n# after\nfrom tradingagents.dataflows.errors import NoMarketDataError\ntry:\n    report = get_fundamentals('ZZZZ.ZY')\nexcept NoMarketDataError:\n    report = None  # stub profile; no usable fundamentals","handlingStrategy":"try-catch","validationCode":"import yfinance as yf\n\ndef fundamentals_are_usable(symbol: str) -> bool:\n    info = yf.Ticker(symbol).info or {}\n    return any(info.get(k) is not None for k in ('longName', 'sector', 'marketCap', 'trailingPE'))","typeGuard":null,"tryCatchPattern":"from tradingagents.dataflows.errors import NoMarketDataError\n\ntry:\n    report = get_fundamentals(symbol)\nexcept NoMarketDataError:\n    report = None  # stub profile — treat as unavailable, don't retry","preventionTips":["Check at least one concrete field (longName/sector) rather than truthiness of info.","Keep yfinance current — stub shapes change between versions.","Log the symbol whenever this fires so bad tickers get pruned from your universe."],"tags":["market-data","yfinance","fundamentals","stub-response"],"backgroundTag":null,"analyzedSha":"a33fd4c0f134485a43553a2c23a63cb14adbd88f","analyzedAt":"2026-08-14T19:45:16.920Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}