{"record":{"id":"84f20c29eda7ecac","repo":"microsoft/qlib","slug":"invalid-mount-path-mount-path-please-mount-man","errorCode":null,"errorMessage":"Invalid mount path: {mount_path}! Please mount manually: {' '.join(mount_command)} or Set init parameter `auto_mount=True`","messagePattern":"Invalid mount path: (.+?)! Please mount manually: (.+?) or Set init parameter `auto_mount=True`","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"error","filePath":"qlib/__init__.py","lineNumber":100,"sourceCode":"    logger.info(\"qlib successfully initialized based on %s settings.\" % default_conf)\n    data_path = {_freq: C.dpm.get_data_uri(_freq) for _freq in C.dpm.provider_uri.keys()}\n    logger.info(f\"data_path={data_path}\")\n\n\ndef _mount_nfs_uri(provider_uri, mount_path, auto_mount: bool = False):\n    LOG = get_module_logger(\"mount nfs\", level=logging.INFO)\n    if mount_path is None:\n        raise ValueError(f\"Invalid mount path: {mount_path}!\")\n    if not re.match(r\"^[a-zA-Z0-9.:/\\-_]+$\", provider_uri):\n        raise ValueError(f\"Invalid provider_uri format: {provider_uri}\")\n    # FIXME: the C[\"provider_uri\"] is modified in this function\n    # If it is not modified, we can pass only  provider_uri or mount_path instead of C\n    mount_command = [\"sudo\", \"mount.nfs\", provider_uri, mount_path]\n    # If the provider uri looks like this 172.23.233.89//data/csdesign'\n    # It will be a nfs path. The client provider will be used\n    if not auto_mount:  # pylint: disable=R1702\n        if not Path(mount_path).exists():\n            raise FileNotFoundError(\n                f\"Invalid mount path: {mount_path}! Please mount manually: {' '.join(mount_command)} or Set init parameter `auto_mount=True`\"\n            )\n    else:\n        # Judging system type\n        sys_type = platform.system()\n        if \"windows\" in sys_type.lower():\n            # system: window\n            try:\n                subprocess.run(\n                    [\"mount\", \"-o\", \"anon\", provider_uri, mount_path],\n                    capture_output=True,\n                    text=True,\n                    check=True,\n                )\n                LOG.info(\"Mount finished.\")\n            except subprocess.CalledProcessError as e:\n                error_output = (e.stdout or \"\") + (e.stderr or \"\")\n                if e.returncode == 85:","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/__init__.py#L82-L118","documentation":"Raised by the module-level file-reading helper in scripts/dump_bin.py (used by DumpDataBase._get_source_data and friends). It dispatches on the file suffix and only knows how to read .csv (via pd.read_csv) and .parquet (via pd.read_parquet); any other suffix reaches the else branch and is rejected. It exists so that dump_bin can ingest either CSV or Parquet source files with per-format kwargs (e.g. low_memory only for CSV).","triggerScenarios":"Calling dump_bin.py with a --data dir containing files whose extension is neither .csv nor .parquet (e.g. .txt, .json, .xlsx, .feather, .h5, or extensionless temp/partial download files such as '.csv.part'); a partially downloaded or hidden file like .DS_Store or a lock file in the source directory; case-sensitivity issues such as .CSV on case-sensitive filesystems.","commonSituations":"Mixed-format source directories where most files are CSV but one export is xlsx; leftover partial downloads or editor temp files (~$file.csv, file.csv.tmp) inside the data dir; renaming data files without updating the extension; users assuming dump_bin reads any pandas-compatible format.","solutions":["Inspect the offending file: find <data_dir> -type f ! -name '*.csv' ! -name '*.parquet' — remove temp/partial files or move them out of the data dir.","Convert the unsupported file to CSV or Parquet before dumping (df = pd.read_excel(...); df.to_csv(...)).","If you control the pipeline, standardize the export step to always emit .csv or .parquet and write atomically (write to temp name, then rename) so partial files never carry a final suffix."],"exampleFix":"# before: data_dir contains prices.xlsx alongside prices.csv\npython dump_bin.py dump_all --data_path ./data_dir ... # ValueError: Unsupported file format: .xlsx\n\n# after: convert first, keep only .csv/.parquet in data_dir\nimport pandas as pd\npd.read_excel('data_dir/prices.xlsx').to_csv('data_dir/prices.csv', index=False)","handlingStrategy":"type-guard","validationCode":"from pathlib import Path\nbad = [str(p) for p in Path(data_dir).iterdir() if p.is_file() and p.suffix.lower() not in (\".csv\", \".parquet\")]\nif bad:\n    raise SystemExit(f\"Unsupported source files in {data_dir}: {bad}\")","typeGuard":"from pathlib import Path\n\ndef is_supported_source(p: Path) -> bool:\n    return p.is_file() and p.suffix.lower() in (\".csv\", \".parquet\")","tryCatchPattern":"try:\n    dumper._get_source_data(file_path)\nexcept ValueError as e:\n    if \"Unsupported file format\" in str(e):\n        logger.warning(\"skipping %s: %s\", file_path, e)\n        continue\n    raise","preventionTips":["Write downloads atomically: temp name without a final suffix, then rename to .csv/.parquet only when complete.","Keep the dump source directory dedicated to a single export format; scrub temp/hidden files before dumping."],"tags":["dump-bin","file-format","csv","parquet","data-validation","pandas"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}