{"record":{"id":"2caae4f33621b7a7","repo":"datawhalechina/hello-agents","slug":"unsupported-data-file-format-data-path-suffix","errorCode":null,"errorMessage":"Unsupported data file format: {data_path.suffix}","messagePattern":"Unsupported data file format: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"Co-creation-projects/healer-666-Academic-Data-Agent/src/data_analysis_agent/data_context.py","lineNumber":40,"sourceCode":"    small_sample_warning: bool\n    context_text: str\n    input_kind: str = \"tabular\"\n    background_literature_context: str = \"\"\n    parsed_document_path: Path | None = None\n    pdf_small_table_mode: bool = False\n    candidate_table_count: int = 0\n    selected_table_id: str = \"\"\n    pdf_multi_table_mode: bool = False\n    candidate_table_summaries_text: str = \"\"\n\n\ndef _read_dataframe(data_path: Path) -> pd.DataFrame:\n    suffix = data_path.suffix.lower()\n    if suffix == \".csv\":\n        return pd.read_csv(data_path)\n    if suffix in {\".xls\", \".xlsx\"}:\n        return pd.read_excel(data_path)\n    raise ValueError(f\"Unsupported data file format: {data_path.suffix}\")\n\n\ndef _normalize_background_text(text: str, *, limit: int = 2000) -> str:\n    normalized = \" \".join(str(text or \"\").split()).strip()\n    return normalized[:limit]\n\n\ndef _load_parsed_document_context(parsed_document_path: Path | None) -> tuple[str, Path | None, dict[str, object]]:\n    if parsed_document_path is None or not parsed_document_path.exists():\n        return \"\", None, {}\n\n    try:\n        payload = json.loads(parsed_document_path.read_text(encoding=\"utf-8\"))\n    except Exception:\n        return \"\", parsed_document_path, {}\n\n    if not isinstance(payload, dict):\n        return \"\", parsed_document_path, {}","sourceCodeStart":22,"sourceCodeEnd":58,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/healer-666-Academic-Data-Agent/src/data_analysis_agent/data_context.py#L22-L58","documentation":"`_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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Convert the data to .csv before ingestion: `df.to_csv('data.csv', index=False)`.","Rename plain tab-separated files to .csv only if they are genuinely comma-separated; otherwise convert first.","For .tsv specifically, load with `pd.read_csv(path, sep='\\t')` and save as .csv.","If you control the code, extend the suffix map: add '.tsv' → read_csv(sep='\\t'), '.parquet' → read_parquet."],"exampleFix":"// before\nsuffix = data_path.suffix.lower()\nif suffix == \".csv\":\n    return pd.read_csv(data_path)\nif suffix in {\".xls\", \".xlsx\"}:\n    return pd.read_excel(data_path)\nraise ValueError(f\"Unsupported data file format: {data_path.suffix}\")\n\n# after\nreaders = {\n    \".csv\": lambda p: pd.read_csv(p),\n    \".tsv\": lambda p: pd.read_csv(p, sep=\"\\t\"),\n    \".parquet\": pd.read_parquet,\n    \".json\": pd.read_json,\n    \".xls\": pd.read_excel,\n    \".xlsx\": pd.read_excel,\n}\nif (reader := readers.get(data_path.suffix.lower())) is None:\n    raise ValueError(f\"Unsupported data file format: {data_path.suffix}\")\nreturn reader(data_path)","handlingStrategy":"validation","validationCode":"from pathlib import Path\n\nSUPPORTED = {\".csv\", \".xls\", \".xlsx\"}\n\ndef is_supported_tabular(path: str | Path) -> bool:\n    return Path(path).suffix.lower() in SUPPORTED\n\n# before loading\ndata_file = Path(data_file).with_suffix(\".csv\") if not is_supported_tabular(data_file) else Path(data_file)\n# (convert first: df = pd.read_<orig>(orig); df.to_csv(data_file, index=False))","typeGuard":"from pathlib import Path\nfrom typing import TypeGuard\n\ndef is_tabular_path(value: object) -> TypeGuard[Path]:\n    return isinstance(value, (str, Path)) and Path(value).suffix.lower() in {\".csv\", \".xls\", \".xlsx\"}","tryCatchPattern":"try:\n    ctx = build_data_context(data_path)\nexcept ValueError as e:\n    if \"Unsupported data file format\" in str(e):\n        df = pd.read_parquet(data_path)      # or read_json/read_csv(sep='\\t')\n        data_path = data_path.with_suffix(\".csv\")\n        df.to_csv(data_path, index=False)\n        ctx = build_data_context(data_path)\n    else:\n        raise","preventionTips":["Standardize on .csv exports before handing files to the agent.","Check the suffix at the upload boundary and convert or reject early.","Watch for double extensions like .csv.gz — gunzip first."],"tags":["validation","file-format","pandas","valueerror","python"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}