@@ -219,3 +219,26 @@ def broken_reader(*_args, **_kwargs): # noqa: D401
219219 monkeypatch .setattr (csv_mod .csv , "DictReader" , broken_reader , raising = True )
220220 with pytest .raises (RuntimeError ):
221221 _ = conv .run (sources = [f ], content_column = "a" )
222+
223+ def test_row_mode_ragged_row_does_not_crash (self ):
224+ # A data row with more fields than the header (e.g. an unquoted comma inside a value).
225+ # Previously the surplus value landed under the None key, which broke Document id
226+ # generation (TypeError sorting None against str keys) and aborted the whole batch.
227+ valid = ByteStream (data = b"text,author\r \n fine,Ada\r \n " , meta = {"file_path" : "valid.csv" })
228+ ragged = ByteStream (data = b"text,note\r \n hello,city,state\r \n " , meta = {"file_path" : "ragged.csv" })
229+
230+ conv = CSVToDocument (conversion_mode = "row" )
231+ out = conv .run (sources = [valid , ragged ], content_column = "text" )
232+ docs = out ["documents" ]
233+
234+ # Both sources yielded a Document; the earlier valid source is not lost.
235+ assert len (docs ) == 2
236+ assert docs [0 ].content == "fine"
237+ assert docs [0 ].meta ["author" ] == "Ada"
238+
239+ ragged_doc = docs [1 ]
240+ assert ragged_doc .content == "hello"
241+ assert ragged_doc .meta ["note" ] == "city"
242+ # Surplus value is preserved under an explicit (non-None) string meta key.
243+ assert None not in ragged_doc .meta
244+ assert "state" in ragged_doc .meta ["extra_columns" ]
0 commit comments