microsoft/qlib · error · OSError

mount {provider_uri} on {mount_path} error! Command error

Error message

mount {provider_uri} on {mount_path} error! Command error

What it means

Base ExpressionCache.update (qlib/data/cache.py:378) is the abstract method that brings expression cache files up to date with the latest calendar; it must return 0 (updated), 1 (no need), or 2 (failure). The base class has no update logic, so it raises NotImplementedError. Callers typically invoke this after new trading days are dumped into the data provider.

Source

Thrown at qlib/__init__.py:181

                except Exception as e:
                    raise OSError(
                        f"Failed to create directory {mount_path}, please create {mount_path} manually!"
                    ) from e

                # check nfs-common
                command_res = os.popen("dpkg -l | grep nfs-common")
                command_res = command_res.readlines()
                if not command_res:
                    raise OSError("nfs-common is not found, please install it by execute: sudo apt install nfs-common")
                # manually mount
                try:
                    subprocess.run(mount_command, check=True, capture_output=True, text=True)
                    LOG.info("Mount finished.")
                except subprocess.CalledProcessError as e:
                    if e.returncode == 256:
                        raise OSError("Mount failed: requires sudo or permission denied") from e
                    elif e.returncode == 32512:
                        raise OSError(f"mount {provider_uri} on {mount_path} error! Command error") from e
                    else:
                        raise OSError(f"Mount failed: {e.stderr}") from e
            else:
                LOG.warning(f"{_remote_uri} on {_mount_path} is already mounted")


def init_from_yaml_conf(conf_path, **kwargs):
    """init_from_yaml_conf

    :param conf_path: A path to the qlib config in yml format
    """

    if conf_path is None:
        config = {}
    else:
        with open(conf_path) as f:
            yaml = YAML(typ="safe", pure=True)
            config = yaml.load(f)

View on GitHub (pinned to 79633dd950)

Solutions

  1. Use DiskExpressionCache, whose update() is implemented for the on-disk format
  2. Override update(self, cache_uri, freq='day') -> int in your custom cache to refresh cache files against the newest calendar
  3. Skip calling update if your cache backend does not support incremental refresh (rebuild the cache instead)

Example fix

# before
cache = MyExprCache(provider)  # update() not implemented
cache.update(cache_uri, "day")  # NotImplementedError

# after
from qlib.data.cache import DiskExpressionCache
cache = DiskExpressionCache(provider)
status = cache.update(cache_uri, "day")  # 0/1/2
Defensive patterns

Strategy: type-guard

Validate before calling

from qlib.data.cache import ExpressionCache

assert MyExprCache.update is not ExpressionCache.update, \
    "custom ExpressionCache must implement update() for daily refresh"

Type guard

def supports_update(cache_cls) -> bool:
    return cache_cls.update is not ExpressionCache.update and cache_cls.update is not DatasetCache.update

Try / catch

try:
    status = cache.update(cache_uri, freq)  # 0/1/2
except NotImplementedError:
    # backend cannot incrementally refresh -> rebuild
    shutil.rmtree(cache_dir, ignore_errors=True)
    regenerate_cache()

Prevention

When it happens

Trigger: Calling ExpressionCache.update(cache_uri, freq) — directly or via cache maintenance scripts — on a subclass (or the base class) that does not override update; common after appending new bar data and wanting to extend cached features.

Common situations: Custom expression cache lacking the update hook; calling update on the base provider chain while only DiskExpressionCache implements it.

Related errors


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