diff --git a/src/abstract_validation_base/runner.py b/src/abstract_validation_base/runner.py index 5a3bf3b..450cbc1 100644 --- a/src/abstract_validation_base/runner.py +++ b/src/abstract_validation_base/runner.py @@ -77,7 +77,8 @@ def error_summary(self) -> list[tuple[str, str]]: """ errors: list[tuple[str, str]] = [] for pydantic_err in self.pydantic_errors: - field_name = str(pydantic_err.get("loc", ["unknown"])[-1]) + loc = pydantic_err.get("loc", ()) + field_name = str(loc[-1]) if loc else "unknown" msg = pydantic_err.get("msg", pydantic_err.get("type", "validation_error")) errors.append((field_name, msg)) if self.validator_result: diff --git a/tests/test_runner.py b/tests/test_runner.py index 58d9991..ab7cda1 100644 --- a/tests/test_runner.py +++ b/tests/test_runner.py @@ -108,6 +108,23 @@ def test_error_summary_uses_type_when_msg_missing(self) -> None: errors = result.error_summary assert errors[0][1] == "value_error" + def test_error_summary_handles_empty_loc_tuple(self) -> None: + """Test error_summary handles Pydantic errors with empty loc tuple. + + This can occur with model_validator failures on nested models where + Pydantic may return an empty location tuple. + """ + result: RowResult[SampleModel] = RowResult( + row_index=0, + raw_data={}, + pydantic_errors=[{"type": "value_error", "loc": (), "msg": "Model validation failed"}], + ) + + errors = result.error_summary + assert len(errors) == 1 + assert errors[0][0] == "unknown" # Default when loc is empty + assert errors[0][1] == "Model validation failed" + # ============================================================================= # RunnerStats Unit Tests