Describe the bug
CSVDocumentCleaner deletes a row whose cells say N/A, and both it and CSVDocumentSplitter empty any cell holding one of pandas' default missing-value strings.
pd.read_csv treats the literal strings N/A, NA, n/a, NULL, None, NaN and nan as missing values. Neither component passes keep_default_na=False, and dtype=object does not change it — the string is gone before the dtype is applied. CSVDocumentCleaner then runs dropna(how="all") over those rows, so a row that says "not applicable" in every column is treated as an empty row and removed.
Error message
None. No error, no warning — the document simply comes back smaller.
Expected behavior
A cell that says N/A is a cell with content. N/A is how a person writes "not applicable" and NULL is what a database export writes, so those cells usually carry the answer someone would ask the document for. They should survive cleaning and splitting; only genuinely empty cells should count as empty.
Additional context
Measured on main (7476cef):
from haystack import Document
from haystack.components.preprocessors.csv_document_cleaner import CSVDocumentCleaner
# 1. a row that says N/A everywhere is deleted
csv = "Code,Status\nA1,ok\nN/A,N/A\nA3,ok\n"
CSVDocumentCleaner().run(documents=[Document(content=csv)])["documents"][0].content
# -> 'Code,Status\nA1,ok\nA3,ok\n' the middle row is gone
# 2. a column of statuses is emptied
csv = "Code,Status,Note\nA1,N/A,keep\nA2,NULL,keep\nA3,NA,keep\n"
CSVDocumentCleaner().run(documents=[Document(content=csv)])["documents"][0].content
# -> 'Code,Status,Note\nA1,,keep\nA2,,keep\nA3,,keep\n'
CSVDocumentSplitter produces the same emptied content for case 2.
The fix is one merged default in each component, keeping the caller's override intact:
# cleaner
df = pd.read_csv(StringIO(document.content), header=None, dtype=object, keep_default_na=False)
# splitter
resolved_read_csv_kwargs = {
"header": None, "skip_blank_lines": False, "dtype": object,
"keep_default_na": False, **self.read_csv_kwargs,
}
A genuinely empty cell is unaffected — keep_default_na governs only the string list, not real blanks — so remove_empty_rows / remove_empty_columns keep doing their job.
I have this reproduced with tests and would normally open the PR, but the flood guard on my last PR asks me to hold off until the first two of my open ones are reviewed, so this is the report instead. Say the word and I will send it.
To Reproduce
The two snippets above, against main.
FAQ Check
System:
- OS: macOS
- Haystack version:
main at 7476cef
- Reproduced with the installed
pandas from the dev extras
Describe the bug
CSVDocumentCleanerdeletes a row whose cells sayN/A, and both it andCSVDocumentSplitterempty any cell holding one of pandas' default missing-value strings.pd.read_csvtreats the literal stringsN/A,NA,n/a,NULL,None,NaNandnanas missing values. Neither component passeskeep_default_na=False, anddtype=objectdoes not change it — the string is gone before the dtype is applied.CSVDocumentCleanerthen runsdropna(how="all")over those rows, so a row that says "not applicable" in every column is treated as an empty row and removed.Error message
None. No error, no warning — the document simply comes back smaller.
Expected behavior
A cell that says
N/Ais a cell with content.N/Ais how a person writes "not applicable" andNULLis what a database export writes, so those cells usually carry the answer someone would ask the document for. They should survive cleaning and splitting; only genuinely empty cells should count as empty.Additional context
Measured on
main(7476cef):CSVDocumentSplitterproduces the same emptied content for case 2.The fix is one merged default in each component, keeping the caller's override intact:
A genuinely empty cell is unaffected —
keep_default_nagoverns only the string list, not real blanks — soremove_empty_rows/remove_empty_columnskeep doing their job.I have this reproduced with tests and would normally open the PR, but the flood guard on my last PR asks me to hold off until the first two of my open ones are reviewed, so this is the report instead. Say the word and I will send it.
To Reproduce
The two snippets above, against
main.FAQ Check
System:
mainat7476cefpandasfrom the dev extras