{"record":{"id":"705c5aed47b32327","repo":"OpenBB-finance/OpenBB","slug":"n-join-messages","errorCode":null,"errorMessage":"\\n\".join(messages)","messagePattern":"\\\\n\"\\.join\\(messages\\)","errorType":"exception","errorClass":"OpenBBError","httpStatus":null,"severity":"error","filePath":"openbb_platform/providers/finviz/openbb_finviz/models/key_metrics.py","lineNumber":281,"sourceCode":"                        float(str(fundament.get(\"Dividend %\", None)).replace(\"%\", \"\"))\n                        / 100\n                        if fundament.get(\"Dividend %\", \"-\") != \"-\"\n                        else None\n                    ),\n                }\n            )\n\n            return result\n\n        symbols = query.symbol.split(\",\")\n\n        for symbol in symbols:\n            result = get_one(symbol)\n            if result is not None and result:\n                results.append(result)\n\n        if not results and messages:\n            raise OpenBBError(\"\\n\".join(messages))\n\n        if not results and not messages:\n            raise EmptyDataError(\"No data was returned for any symbol\")\n\n        if results and messages:\n            for message in messages:\n                warn(message)\n\n        return results\n\n    @staticmethod\n    def transform_data(\n        query: FinvizKeyMetricsQueryParams,\n        data: list[dict],\n        **kwargs: Any,\n    ) -> list[FinvizKeyMetricsData]:\n        \"\"\"Transform and validate the raw data.\"\"\"\n        return [FinvizKeyMetricsData.model_validate(d) for d in data]","sourceCodeStart":263,"sourceCodeEnd":299,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/providers/finviz/openbb_finviz/models/key_metrics.py#L263-L299","documentation":"Finviz key metrics fetcher aggregates per-symbol failures: when every requested symbol produced an entry in `messages` (per-symbol errors/warnings collected in get_one) and no results came back, it raises OpenBBError joining all messages with newlines. The joined text identifies which symbols failed and why (usually 'No data found for SYMBOL').","triggerScenarios":"Passing a comma-separated symbol list where every ticker fails on Finviz (invalid, delisted, or no metrics row); upstream HTTP errors for each symbol captured into messages.","commonSituations":"Batch metric pulls over a dirty ticker universe; symbols with exchange-specific spellings Finviz does not accept.","solutions":["Read the joined messages: each line names the failing symbol and reason","Retry with only the symbols that are valid Finviz tickers","Split the batch and process per symbol, skipping failures, if partial data is acceptable"],"exampleFix":"# before\nres = await obb.equity.fundamental.metrics(provider=\"finviz\", symbol=\"ZZZZ,YYYY\")\n# OpenBBError: No data found for ZZZZ\\nNo data found for YYYY\n\n# after\nres = await obb.equity.fundamental.metrics(provider=\"finviz\", symbol=\"AAPL,MSFT\")","handlingStrategy":"try-catch","validationCode":"def split_symbols(raw: str) -> list[str]:\n    return [s.strip() for s in raw.split(\",\") if s.strip()]\n\nsymbols = split_symbols(query_symbol)\nassert symbols, \"symbol list empty\"","typeGuard":null,"tryCatchPattern":"from openbb_core.app.model.obb_error import OpenBBError\n\ntry:\n    results = await FinvizKeyMetricsFetcher.transform_query(...)\nexcept OpenBBError as e:\n    failed = [ln for ln in str(e).splitlines() if \"No data\" in ln]\n    # drop the named symbols and retry the remainder","preventionTips":["Pre-validate tickers against Finviz coverage before batch metric pulls","Parse the per-line messages to identify failing symbols automatically","Process symbols individually and skip failures when partial results suffice"],"tags":["openbb","finviz","batch","symbol-validation","key-metrics"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}