{"record":{"id":"45278a3b4add15f6","repo":"ZhuLinsen/daily_stock_analysis","slug":"unsupported-candidate-context-file-format-path","errorCode":null,"errorMessage":"Unsupported candidate context file format: {path}","messagePattern":"Unsupported candidate context file format: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/services/screening/context.py","lineNumber":437,"sourceCode":"                if isinstance(item, dict):\n                    rows.append(item)\n        return rows\n    if suffix == \".json\":\n        data = json.loads(path.read_text(encoding=\"utf-8\"))\n        if isinstance(data, list):\n            return [item for item in data if isinstance(item, dict)]\n        if isinstance(data, dict):\n            items = data.get(\"items\") or data.get(\"data\")\n            if isinstance(items, list):\n                return [item for item in items if isinstance(item, dict)]\n            rows = []\n            for code, value in data.items():\n                if isinstance(value, dict):\n                    rows.append({\"code\": code, **value})\n                elif isinstance(value, str):\n                    rows.append({\"code\": code, \"text\": value})\n            return rows\n    raise ValueError(f\"Unsupported candidate context file format: {path}\")\n\n\ndef _safe_context_value(value: object, *, max_len: int = 280) -> str:\n    if value is None:\n        return \"\"\n    if isinstance(value, list):\n        text = \",\".join(str(item).strip() for item in value if str(item).strip())\n    else:\n        text = str(value).strip()\n    if not text or text.lower() in {\"nan\", \"none\", \"<na>\"}:\n        return \"\"\n    return text[:max_len]\n\n\ndef _format_profile_value(value: object) -> str:\n    if isinstance(value, list):\n        return \"，\".join(\n            item","sourceCodeStart":419,"sourceCodeEnd":455,"githubUrl":"https://github.com/ZhuLinsen/daily_stock_analysis/blob/5159bd72e8373d215492dff122acc9d389e219c9/src/services/screening/context.py#L419-L455","documentation":"ValueError raised by _load_candidate_context_rows when the file suffix is not .csv, .jsonl, or .json — the only three formats the candidate-context loader parses. The error fires purely on extension, so a valid CSV named .txt or .xlsx raises before any content is read.","triggerScenarios":"Passing a candidate context file with an unsupported extension: .txt, .xlsx, .tsv, .md, or no suffix at all. The suffix check (path.suffix.lower()) dispatches format parsing, and everything outside the three handled branches falls through to the raise at src/services/screening/context.py:437.","commonSituations":"Users exporting Excel (.xlsx) from a data team; renaming files to .txt; uppercase extensions work (.CSV is fine via .lower()) but compressed variants (.json.gz, .csv.gz) do not; a path whose trailing dot or query string corrupts the suffix.","solutions":["Rename or export the file to one of the supported suffixes: .csv, .json, or .jsonl.","If the data lives in Excel, convert first: df = pd.read_excel(p); df.to_csv(p.with_suffix('.csv'), index=False).","For gzipped files, decompress before passing: gzip.decompress(...) written to a .json/.csv path.","Validate extensions before the run: assert Path(p).suffix.lower() in {'.csv', '.json', '.jsonl'} with a clear message."],"exampleFix":"# before\nread_candidate_context_files(['watchlist.xlsx'], df)  # ValueError\n\n# after: convert once at the boundary\nwatch = pd.read_excel('watchlist.xlsx')\nwatch.to_csv('watchlist.csv', index=False)\nread_candidate_context_files(['watchlist.csv'], df)","handlingStrategy":"validation","validationCode":"from pathlib import Path\nSUPPORTED = {'.csv', '.json', '.jsonl'}\nbad = [p for p in candidate_context_paths if Path(p).suffix.lower() not in SUPPORTED]\nif bad:\n    raise ValueError(f'candidate context must be .csv/.json/.jsonl: {bad}')","typeGuard":"from pathlib import Path\ndef is_supported_context_file(path: str | Path) -> bool:\n    return Path(path).suffix.lower() in {'.csv', '.json', '.jsonl'}","tryCatchPattern":null,"preventionTips":["Standardize candidate context artifacts on .csv/.json/.jsonl in the pipeline.","Convert Excel exports at the boundary with to_csv/with_suffix('.csv').","Validate suffixes during config load so a bad path fails fast, not mid-run."],"tags":["screening","candidate-context","file-format","validation"],"backgroundTag":null,"analyzedSha":"5159bd72e8373d215492dff122acc9d389e219c9","analyzedAt":"2026-08-15T01:59:36.292Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}