microsoft/qlib · warning · OSError

Unknown mount error: {error_output.strip()}

Error message

Unknown mount error: {error_output.strip()}

What it means

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.

Source

Thrown at qlib/__init__.py:125

            # system: window
            try:
                subprocess.run(
                    ["mount", "-o", "anon", provider_uri, mount_path],
                    capture_output=True,
                    text=True,
                    check=True,
                )
                LOG.info("Mount finished.")
            except subprocess.CalledProcessError as e:
                error_output = (e.stdout or "") + (e.stderr or "")
                if e.returncode == 85:
                    LOG.warning(f"{provider_uri} already mounted at {mount_path}")
                elif e.returncode == 53:
                    raise OSError("Network path not found") from e
                elif "error" in error_output.lower() or "错误" in error_output:
                    raise OSError("Invalid mount path") from e
                else:
                    raise OSError(f"Unknown mount error: {error_output.strip()}") from e
        else:
            # system: linux/Unix/Mac
            # check mount
            _remote_uri = provider_uri[:-1] if provider_uri.endswith("/") else provider_uri
            # `mount a /b/c` is different from `mount a /b/c/`. So we convert it into string to make sure handling it accurately
            mount_path = str(mount_path)
            _mount_path = mount_path[:-1] if mount_path.endswith("/") else mount_path
            _check_level_num = 2
            _is_mount = False
            while _check_level_num:
                with subprocess.Popen(
                    ["mount"],
                    text=True,
                    stdout=subprocess.PIPE,
                    stderr=subprocess.STDOUT,
                ) as shell_r:
                    _command_log = shell_r.stdout.readlines()
                    _command_log = [line for line in _command_log if _remote_uri in line]

View on GitHub (pinned to 79633dd950)

Solutions

  1. This is non-fatal by design (logged as warning) — cache regeneration still works; ignore unless cache hit rates look wrong
  2. Delete the affected cache directory (e.g. <data_dir>/features_cache or dataset cache dir) so qlib regenerates .meta files with the current schema
  3. Avoid running multiple cache-writing jobs concurrently on the same data URI, or use the redis-based writer lock if configured
  4. Upgrade qlib so cache-writing and cache-reading versions share one meta schema

Example fix

# remove stale cache files so meta is regenerated with current schema
rm -rf ~/.qlib/qlib_data/cn_data/features_cache  # path depends on your provider_uri
qlib.init(provider_uri="~/.qlib/qlib_data/cn_data", region="cn")
Defensive patterns

Strategy: try-catch

Validate before calling

from pathlib import Path

def meta_is_intact(cache_path: Path) -> bool:
    meta = cache_path.with_suffix(".meta")
    if not meta.exists():
        return False
    import pickle
    d = pickle.loads(meta.read_bytes())
    return isinstance(d, dict) and "meta" in d and "visits" in d["meta"]

Try / catch

# CacheUtils.visit already swallows this and logs a warning;
# only act if cache hit rates regress:
try:
    CacheUtils.visit(cache_path)
except KeyError:
    cache_path.with_suffix(".meta").unlink(missing_ok=True)  # force regeneration

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15). Data as JSON: /api/errors/5ed97f8968b97c31. Report an issue: GitHub.