datawhalechina/hello-agents · error · ValueError

Unsupported data file format: {data_path.suffix}

Error message

Unsupported data file format: {data_path.suffix}

What it means

`_read_dataframe` dispatches on the lowercased file suffix and supports only .csv (pd.read_csv) and .xls/.xlsx (pd.read_excel); any other suffix (e.g. .parquet, .json, .tsv, .txt) raises ValueError 'Unsupported data file format: {suffix}'. It is the format gate for tabular data ingestion.

Source

Thrown at Co-creation-projects/healer-666-Academic-Data-Agent/src/data_analysis_agent/data_context.py:40

    small_sample_warning: bool
    context_text: str
    input_kind: str = "tabular"
    background_literature_context: str = ""
    parsed_document_path: Path | None = None
    pdf_small_table_mode: bool = False
    candidate_table_count: int = 0
    selected_table_id: str = ""
    pdf_multi_table_mode: bool = False
    candidate_table_summaries_text: str = ""


def _read_dataframe(data_path: Path) -> pd.DataFrame:
    suffix = data_path.suffix.lower()
    if suffix == ".csv":
        return pd.read_csv(data_path)
    if suffix in {".xls", ".xlsx"}:
        return pd.read_excel(data_path)
    raise ValueError(f"Unsupported data file format: {data_path.suffix}")


def _normalize_background_text(text: str, *, limit: int = 2000) -> str:
    normalized = " ".join(str(text or "").split()).strip()
    return normalized[:limit]


def _load_parsed_document_context(parsed_document_path: Path | None) -> tuple[str, Path | None, dict[str, object]]:
    if parsed_document_path is None or not parsed_document_path.exists():
        return "", None, {}

    try:
        payload = json.loads(parsed_document_path.read_text(encoding="utf-8"))
    except Exception:
        return "", parsed_document_path, {}

    if not isinstance(payload, dict):
        return "", parsed_document_path, {}

View on GitHub (pinned to 606a07d341)

Solutions

  1. Convert the data to .csv before ingestion: `df.to_csv('data.csv', index=False)`.
  2. Rename plain tab-separated files to .csv only if they are genuinely comma-separated; otherwise convert first.
  3. For .tsv specifically, load with `pd.read_csv(path, sep='\t')` and save as .csv.
  4. If you control the code, extend the suffix map: add '.tsv' → read_csv(sep='\t'), '.parquet' → read_parquet.

Example fix

// before
suffix = data_path.suffix.lower()
if suffix == ".csv":
    return pd.read_csv(data_path)
if suffix in {".xls", ".xlsx"}:
    return pd.read_excel(data_path)
raise ValueError(f"Unsupported data file format: {data_path.suffix}")

# after
readers = {
    ".csv": lambda p: pd.read_csv(p),
    ".tsv": lambda p: pd.read_csv(p, sep="\t"),
    ".parquet": pd.read_parquet,
    ".json": pd.read_json,
    ".xls": pd.read_excel,
    ".xlsx": pd.read_excel,
}
if (reader := readers.get(data_path.suffix.lower())) is None:
    raise ValueError(f"Unsupported data file format: {data_path.suffix}")
return reader(data_path)
Defensive patterns

Strategy: validation

Validate before calling

from pathlib import Path

SUPPORTED = {".csv", ".xls", ".xlsx"}

def is_supported_tabular(path: str | Path) -> bool:
    return Path(path).suffix.lower() in SUPPORTED

# before loading
data_file = Path(data_file).with_suffix(".csv") if not is_supported_tabular(data_file) else Path(data_file)
# (convert first: df = pd.read_<orig>(orig); df.to_csv(data_file, index=False))

Type guard

from pathlib import Path
from typing import TypeGuard

def is_tabular_path(value: object) -> TypeGuard[Path]:
    return isinstance(value, (str, Path)) and Path(value).suffix.lower() in {".csv", ".xls", ".xlsx"}

Try / catch

try:
    ctx = build_data_context(data_path)
except ValueError as e:
    if "Unsupported data file format" in str(e):
        df = pd.read_parquet(data_path)      # or read_json/read_csv(sep='\t')
        data_path = data_path.with_suffix(".csv")
        df.to_csv(data_path, index=False)
        ctx = build_data_context(data_path)
    else:
        raise

Prevention

When it happens

Trigger: Pointing the agent at a .tsv (readable by pandas but not routed), a .parquet or .json dataset, a file with no extension, or a URL whose suffix component is empty/odd; note suffix matching is exact-lowercase, so .CSV works but .csv.gz does not.

Common situations: Users exporting data from databases/tools as parquet or jsonl; datasets with double extensions (.csv.gz); tab-separated exports named .tsv/.txt that pandas could handle if routed.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/2caae4f33621b7a7. Report an issue: GitHub.