{"record":{"id":"5ed97f8968b97c31","repo":"microsoft/qlib","slug":"unknown-mount-error-error-output-strip","errorCode":null,"errorMessage":"Unknown mount error: {error_output.strip()}","messagePattern":"Unknown mount error: (.+?)","errorType":"exception","errorClass":"OSError","httpStatus":null,"severity":"warning","filePath":"qlib/__init__.py","lineNumber":125,"sourceCode":"            # 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:\n                    LOG.warning(f\"{provider_uri} already mounted at {mount_path}\")\n                elif e.returncode == 53:\n                    raise OSError(\"Network path not found\") from e\n                elif \"error\" in error_output.lower() or \"错误\" in error_output:\n                    raise OSError(\"Invalid mount path\") from e\n                else:\n                    raise OSError(f\"Unknown mount error: {error_output.strip()}\") from e\n        else:\n            # system: linux/Unix/Mac\n            # check mount\n            _remote_uri = provider_uri[:-1] if provider_uri.endswith(\"/\") else provider_uri\n            # `mount a /b/c` is different from `mount a /b/c/`. So we convert it into string to make sure handling it accurately\n            mount_path = str(mount_path)\n            _mount_path = mount_path[:-1] if mount_path.endswith(\"/\") else mount_path\n            _check_level_num = 2\n            _is_mount = False\n            while _check_level_num:\n                with subprocess.Popen(\n                    [\"mount\"],\n                    text=True,\n                    stdout=subprocess.PIPE,\n                    stderr=subprocess.STDOUT,\n                ) as shell_r:\n                    _command_log = shell_r.stdout.readlines()\n                    _command_log = [line for line in _command_log if _remote_uri in line]","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/__init__.py#L107-L143","documentation":"CacheUtils.visit (qlib/data/cache.py:235) opens a cache file's .meta pickle, updates d[\"meta\"][\"last_visit\"] and d[\"meta\"][\"visits\"], and raises KeyError('Unknown meta keyword') if the 'meta' sub-dict (or its keys) is missing. This indicates a corrupted or stale .meta file. Note the whole operation is wrapped in a broad except that logs a warning — so in practice the raised KeyError is swallowed, and you normally see it only as 'visit <path> cache error: ...' in logs.","triggerScenarios":"A disk cache file's companion .meta file exists but lacks the 'meta'/'visits' structure — e.g. written by an older qlib version with a different meta schema, truncated by a crash mid-write (the FIXME notes read locks were removed), or touched by multiple concurrent processes.","commonSituations":"After upgrading qlib with caches on disk from an older release; parallel data-preparation jobs racing on the same cache directory; a killed process leaving half-written .meta files.","solutions":["This is non-fatal by design (logged as warning) — cache regeneration still works; ignore unless cache hit rates look wrong","Delete the affected cache directory (e.g. <data_dir>/features_cache or dataset cache dir) so qlib regenerates .meta files with the current schema","Avoid running multiple cache-writing jobs concurrently on the same data URI, or use the redis-based writer lock if configured","Upgrade qlib so cache-writing and cache-reading versions share one meta schema"],"exampleFix":"# remove stale cache files so meta is regenerated with current schema\nrm -rf ~/.qlib/qlib_data/cn_data/features_cache  # path depends on your provider_uri\nqlib.init(provider_uri=\"~/.qlib/qlib_data/cn_data\", region=\"cn\")","handlingStrategy":"try-catch","validationCode":"from pathlib import Path\n\ndef meta_is_intact(cache_path: Path) -> bool:\n    meta = cache_path.with_suffix(\".meta\")\n    if not meta.exists():\n        return False\n    import pickle\n    d = pickle.loads(meta.read_bytes())\n    return isinstance(d, dict) and \"meta\" in d and \"visits\" in d[\"meta\"]","typeGuard":null,"tryCatchPattern":"# CacheUtils.visit already swallows this and logs a warning;\n# only act if cache hit rates regress:\ntry:\n    CacheUtils.visit(cache_path)\nexcept KeyError:\n    cache_path.with_suffix(\".meta\").unlink(missing_ok=True)  # force regeneration","preventionTips":["Wipe cache dirs after qlib major upgrades","Run one cache-writing job per data URI at a time","Treat 'visit ... cache error' warnings as a signal to regenerate cache"],"tags":["qlib","disk-cache","corruption","concurrency","meta"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}