deepset-ai/haystack · error

Unsupported export format: {table_format}. Choose either 'cs

Error message

Unsupported export format: {table_format}. Choose either 'csv' or 'markdown'.

What it means

XLSXToDocument's __init__ validates the table_format option: only 'csv' or 'markdown' are supported for exporting tables inside the spreadsheet. Any other value raises ValueError at construction time, before any file is read.

Source

Thrown at haystack/components/converters/xlsx.py:83

        :param read_excel_kwargs: Additional arguments to pass to `pandas.read_excel`.
            See https://pandas.pydata.org/docs/reference/api/pandas.read_excel.html#pandas-read-excel
        :param table_format_kwargs: Additional keyword arguments to pass to the table format function.
            - If `table_format` is "csv", these arguments are passed to `pandas.DataFrame.to_csv`.
              See https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_csv.html#pandas-dataframe-to-csv
            - If `table_format` is "markdown", these arguments are passed to `pandas.DataFrame.to_markdown`.
              See https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.to_markdown.html#pandas-dataframe-to-markdown
        :param link_format: The format for link output. Possible options:
            - `"markdown"`: `[text](url)`
            - `"plain"`: `text (url)`
            - `"none"`: Only the text is extracted, link addresses are ignored.
        :param store_full_path:
            If True, the full path of the file is stored in the metadata of the document.
            If False, only the file name is stored.
        """
        pandas_xlsx_import.check()
        self.table_format = table_format
        if table_format not in ["csv", "markdown"]:
            raise ValueError(f"Unsupported export format: {table_format}. Choose either 'csv' or 'markdown'.")
        if link_format not in ("markdown", "plain", "none"):
            msg = f"Unknown link format '{link_format}'. Supported formats are: 'markdown', 'plain', 'none'"
            raise ValueError(msg)
        if table_format == "markdown":
            tabulate_import.check()
        self.link_format = link_format
        self.sheet_name = sheet_name
        self.read_excel_kwargs = read_excel_kwargs or {}
        self.table_format_kwargs = table_format_kwargs or {}
        self.store_full_path = store_full_path

    @component.output_types(documents=list[Document])
    def run(
        self, sources: list[str | Path | ByteStream], meta: dict[str, Any] | list[dict[str, Any]] | None = None
    ) -> dict[str, list[Document]]:
        """
        Converts a XLSX file to a Document.

View on GitHub (pinned to e318778c9b)

Solutions

  1. Set table_format='markdown' (rich table rendering; requires tabulate) or table_format='csv'.
  2. Match casing exactly — the check is case-sensitive.
  3. If you need another format, post-process the Documents yourself instead of via table_format.

Example fix

# before
converter = XLSXToDocument(table_format="json")
# after
converter = XLSXToDocument(table_format="markdown")
Defensive patterns

Strategy: validation

Validate before calling

VALID_TABLE_FORMATS = ("csv", "markdown")

def is_valid_table_format(fmt: str) -> bool:
    return fmt in VALID_TABLE_FORMATS

assert is_valid_table_format(table_format), f"{table_format!r} not in {VALID_TABLE_FORMATS}"

Type guard

from typing import Literal
TableFormat = Literal["csv", "markdown"]

def is_table_format(s: str) -> bool:
    return s in ("csv", "markdown")

Try / catch

try:
    converter = XLSXToDocument(table_format=fmt)
except ValueError as e:
    logger.warning("Invalid table_format %s, defaulting to markdown", e)
    converter = XLSXToDocument(table_format="markdown")

Prevention

When it happens

Trigger: Instantiating XLSXToDocument(table_format=...) with a value other than 'csv' or 'markdown', e.g. 'excel', 'json', 'html', or 'Markdown' (case-sensitive).

Common situations: Typo or wrong casing in pipeline YAML; expecting other pandas to_* output formats; copying a table_format value from a different converter component.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30). Data as JSON: /api/errors/4dd479b2d36db30c. Report an issue: GitHub.