{"record":{"id":"a842af14087829f8","repo":"OpenBB-finance/OpenBB","slug":"failed-to-convert-dictionary-of-lists-to-list-of-r","errorCode":null,"errorMessage":"Failed to convert dictionary of lists to list of records","messagePattern":"Failed to convert dictionary of lists to list of records","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/extensions/platform_api/openbb_platform_api/response_models.py","lineNumber":262,"sourceCode":"            isinstance(item, dict) for item in content\n        ):\n            values.parse_as = \"table\"\n        elif isinstance(content, pd.DataFrame):\n            values.parse_as = \"table\"\n            try:\n                content = json.loads(content.to_json(orient=\"records\"))\n            except Exception as e:\n                raise ValueError(\"Failed to convert DataFrame to JSON\") from e\n            values.content = content\n        elif isinstance(content, dict) and all(\n            isinstance(v, list) for v in content.values()\n        ):\n            values.parse_as = \"table\"\n            try:\n                df = pd.DataFrame(content)\n                content = json.loads(df.to_json(orient=\"records\"))\n            except Exception as e:\n                raise ValueError(\n                    \"Failed to convert dictionary of lists to list of records\"\n                ) from e\n            values.content = content\n        elif isinstance(content, str) and content.strip():  # pylint: disable=R0916\n            try:\n                content = json.loads(content)\n            except json.JSONDecodeError:\n                # Remove trailing commas in objects and arrays\n                try:\n                    cleaned_content = re.sub(r\",(\\s*[}\\]])\", r\"\\1\", content)\n                    content = json.loads(cleaned_content)\n                except json.JSONDecodeError:\n                    pass\n\n            values.parse_as = \"table\" if isinstance(content, (list, dict)) else \"text\"\n            values.content = content\n        else:\n            values.parse_as = \"text\"","sourceCodeStart":244,"sourceCodeEnd":280,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/extensions/platform_api/openbb_platform_api/response_models.py#L244-L280","documentation":"Thrown by the OmniWidgetResponseModel model_validator when content is a dict whose values are all lists (the column->list table shape) but building a DataFrame from it and serializing to records fails. This is the dict-of-lists table conversion path; failures are chained into this ValueError.","triggerScenarios":"Constructing OmniWidgetResponseModel(content={'col_a': [...], 'col_b': [...]}) where list lengths differ (ValueError in pd.DataFrame construction), or the lists contain objects pandas/json cannot encode.","commonSituations":"Assembling a dict-of-lists from heterogeneous loops where one list ends up shorter or longer; embedding Timestamps, Decimals, or model objects inside the lists; an empty dict {} with other code paths mutating values.","solutions":["Verify all value lists have equal length: assert len({len(v) for v in content.values()}) == 1.","Coerce non-serializable elements to primitives (str/float/int) before constructing the model.","Build the records list yourself (list(zip(...)) -> list of dicts) and pass it as content so the list-of-dicts branch is used.","Check e.__cause__ for the exact pandas error (usually 'All arrays must be of the same length')."],"exampleFix":"# before\ncontent = {\"a\": [1, 2], \"b\": [3]}  # ragged\nresp = OmniWidgetResponseModel(content=content)\n\n# after\ncontent = {\"a\": [1, 2], \"b\": [3, 4]}\nresp = OmniWidgetResponseModel(content=content)","handlingStrategy":"validation","validationCode":"lengths = {len(v) for v in content.values() if isinstance(v, list)}\nassert len(lengths) <= 1, f\"ragged columns: {lengths}\"\nrecords = [dict(zip(content, row)) for row in zip(*content.values())]\nresp = OmniWidgetResponseModel(content=records)","typeGuard":"def is_wellformed_dict_of_lists(d) -> bool:\n    return isinstance(d, dict) and bool(d) and all(\n        isinstance(v, list) for v in d.values()\n    ) and len({len(v) for v in d.values()}) == 1","tryCatchPattern":"try:\n    resp = OmniWidgetResponseModel(content=table_dict)\nexcept ValueError as e:\n    if \"dictionary of lists\" in str(e):\n        raise ValueError(f\"ragged table: { {k: len(v) for k, v in table_dict.items()} }\") from e\n    raise","preventionTips":["Build dict-of-lists from a single loop so lengths stay aligned","Assert equal list lengths at construction time","Prefer passing a DataFrame or list of records directly"],"tags":["pandas","serialization","pydantic","validation"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}