microsoft/qlib · warning · OSError
Mount failed: requires sudo or permission denied
Error message
Mount failed: requires sudo or permission denied
What it means
Base ExpressionCache._expression (qlib/data/cache.py:360) is the abstract method that actually reads expression data from the cache. The base raises NotImplementedError('Implement this method if you want to use expression cache'); the public expression() wrapper catches that NotImplementedError and transparently falls back to self.provider.expression(...), i.e. without a cache you silently pay the cost of loading from the underlying provider.
Source
Thrown at qlib/__init__.py:179
try:
Path(mount_path).mkdir(parents=True, exist_ok=True)
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:View on GitHub (pinned to 79633dd950)
Solutions
- Use the shipped qlib.data.cache.DiskExpressionCache if file-based caching is what you want
- Override _expression(self, instrument, field, start_time, end_time, freq) -> pd.Series in your subclass to read from your cache backend
- Pair it with _uri and update overrides — all three must be consistent
Example fix
# before qlib.init(expression_cache=MyBrokenCache) # _expression not overridden -> no caching # after from qlib.data.cache import DiskExpressionCache qlib.init(expression_cache=DiskExpressionCache, expression_cache_disk_path=...)
Defensive patterns
Strategy: fallback
Validate before calling
from qlib.data.cache import ExpressionCache
if MyExprCache._expression is ExpressionCache._expression:
print("WARNING: expression cache disabled (falls back to provider)") Try / catch
# expression() already falls back to the provider on NotImplementedError; # detect the silent no-cache path by timing or by checking cache dir growth
Prevention
- Confirm cache files actually appear after runs; silent fallback makes caches a no-op
- Base custom caches on DiskExpressionCache when possible
- Alert when cache hit counters stay at zero
When it happens
Trigger: Registering a custom ExpressionCache subclass without overriding _expression: data still loads (via provider fallback) but nothing is cached; calling _expression directly always raises; subclass forgot to also override _uri, in which case uri-related calls fail separately.
Common situations: Boilerplate custom cache classes where only the constructor was customized; misreading the API — assuming the base class provides a default file-based cache (it does not; that is DiskExpressionCache).
Related errors
- nfs-common is not found, please install it by execute: sudo
- mount {provider_uri} on {mount_path} error! Command error
- Mount failed: {e.stderr}
- We can't find the project path
- account must be in (int, float, dict)
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/02d39a103ac25203.
Report an issue: GitHub.