{"record":{"id":"2b5f2badbc1d4001","repo":"OpenBB-finance/OpenBB","slug":"validation-error-when-converting-dict-to-basemodel","errorCode":null,"errorMessage":"Validation error when converting dict to BaseModel: {e}","messagePattern":"Validation error when converting dict to BaseModel: (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"openbb_platform/core/openbb_core/app/utils.py","lineNumber":115,"sourceCode":"    base_models = []\n    for item in data_list:\n        if isinstance(item, Data) or issubclass(type(item), Data):\n            base_models.append(item)\n        elif isinstance(item, dict):\n            base_models.append(Data(**item))\n        elif isinstance(item, (DataFrame, Series)):\n            base_models.extend(df_to_basemodel(item))\n        else:\n            raise ValueError(f\"Unsupported list item type: {type(item)}\")\n    return base_models\n\n\ndef dict_to_basemodel(data_dict: dict) -> Data:\n    \"\"\"Convert a dictionary to BaseModel.\"\"\"\n    try:\n        return Data(**data_dict)\n    except ValidationError as e:\n        raise ValueError(\n            f\"Validation error when converting dict to BaseModel: {e}\"\n        ) from e\n\n\ndef ndarray_to_basemodel(array: \"ndarray\") -> list[Data]:\n    \"\"\"Convert a NumPy array to list of BaseModel.\"\"\"\n    # Assuming a 2D array where rows are records\n    if array.ndim != 2:\n        raise ValueError(\"Only 2D arrays are supported.\")\n    return [\n        Data(**{f\"column_{i}\": value for i, value in enumerate(row)}) for row in array\n    ]\n\n\ndef convert_to_basemodel(data) -> Data | list[Data]:\n    \"\"\"Dispatch function to convert different types to BaseModel.\"\"\"\n    # pylint: disable=import-outside-toplevel\n    from numpy import ndarray","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/OpenBB-finance/OpenBB/blob/3e071fcc2cd9f891cac6040ae60296dba76dab46/openbb_platform/core/openbb_core/app/utils.py#L97-L133","documentation":"ValueError raised by dict_to_basemodel when constructing the generic Data(**data_dict) model raises a Pydantic ValidationError - e.g. a field fails coercion (str where number expected) or an unknown/misconfigured constraint. The original ValidationError is chained as the cause, so details of the failing field are preserved in e.","triggerScenarios":"convert_to_basemodel({'close': 'n/a'}) where the dict came from a provider row whose string values cannot coerce to the declared field types; nested dicts that Data rejects; keys with None for required fields in strict contexts.","commonSituations":"Provider responses containing placeholder strings ('-', 'N/A') in numeric columns; malformed API payloads after schema drift; user code hand-building dicts with wrong key casing (aliases not enabled) so validation fails.","solutions":["Inspect the chained ValidationError (raise ... from e) for the exact field and reason","Clean the dict before conversion: strip 'N/A'/'-' placeholders, cast numerics, drop or fix invalid keys","If writing a provider, do the coercion in the fetcher/transform step instead of relying on Data","Upgrade the provider package if upstream parsing was fixed"],"exampleFix":"# before\nrow = {'date': '2024-01-02', 'close': 'N/A'}\nmodel = convert_to_basemodel(row)\n\n# after\nrow = {'date': '2024-01-02', 'close': None}\nmodel = convert_to_basemodel(row)","handlingStrategy":"validation","validationCode":"def clean_row(d: dict) -> dict:\n    return {\n        k: (None if isinstance(v, str) and v.strip() in {'', '-', 'N/A', 'n/a'} else v)\n        for k, v in d.items()\n    }","typeGuard":"def is_valid_row(d: dict) -> bool:\n    try:\n        Data(**d)\n        return True\n    except Exception:\n        return False","tryCatchPattern":"try:\n    model = dict_to_basemodel(row)\nexcept ValueError as e:\n    logger.warning('skipping invalid row %s: %s', row, e.__cause__)\n    model = None  # skip bad record in ETL loops","preventionTips":["Sanitize placeholder strings ('N/A', '-') to None before conversion","Coerce numeric strings at ingestion time","Log and skip individual bad rows instead of failing the whole batch"],"tags":["openbb","pydantic","type-conversion","validation"],"backgroundTag":null,"analyzedSha":"3e071fcc2cd9f891cac6040ae60296dba76dab46","analyzedAt":"2026-08-14T23:40:48.960Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}