microsoft/qlib · critical · ValueError
provider_uri cannot be None
Error message
provider_uri cannot be None
What it means
QlibConfig.DataPathManager.format_provider_uri in qlib/config.py normalizes the provider_uri argument into a {freq: uri} dict. None is explicitly rejected with ValueError because data access requires at least one concrete location. This typically surfaces when qlib.init is called with provider_uri=None (the default of a partially-filled config) or a nested call re-formats the uri.
Source
Thrown at qlib/config.py:364
"""
Motivation:
- get the right path (e.g. data uri) for accessing data based on given information(e.g. provider_uri, mount_path and frequency)
- some helper functions to process uri.
"""
def __init__(self, provider_uri: Union[str, Path, dict], mount_path: Union[str, Path, dict]):
"""
The relation of `provider_uri` and `mount_path`
- `mount_path` is used only if provider_uri is an NFS path
- otherwise, provider_uri will be used for accessing data
"""
self.provider_uri = provider_uri
self.mount_path = mount_path
@staticmethod
def format_provider_uri(provider_uri: Union[str, dict, Path]) -> dict:
if provider_uri is None:
raise ValueError("provider_uri cannot be None")
if isinstance(provider_uri, (str, dict, Path)):
if not isinstance(provider_uri, dict):
provider_uri = {QlibConfig.DEFAULT_FREQ: provider_uri}
else:
raise TypeError(f"provider_uri does not support {type(provider_uri)}")
for freq, _uri in provider_uri.items():
if QlibConfig.DataPathManager.get_uri_type(_uri) == QlibConfig.LOCAL_URI:
provider_uri[freq] = str(Path(_uri).expanduser().resolve())
return provider_uri
@staticmethod
def get_uri_type(uri: Union[str, Path]):
uri = uri if isinstance(uri, str) else str(uri.expanduser().resolve())
is_win = re.match("^[a-zA-Z]:.*", uri) is not None # such as 'C:\\data', 'D:'
# such as 'host:/data/' (User may define short hostname by themselves or use localhost)
is_nfs_or_win = re.match("^[^/]+:.+", uri) is not None
if is_nfs_or_win and not is_win:View on GitHub (pinned to 79633dd950)
Solutions
- Set a concrete provider_uri in qlib.init (e.g. '~/.qlib/qlib_data/cn_data').
- Guard before init: if provider_uri from your own config is None, either fail fast with a clear message or substitute the default path.
- For multi-frequency data pass a dict like {'day': uri_day, '1min': uri_min} — never None values.
Example fix
# before
qlib.init(provider_uri=cfg.get('provider_uri')) # None if key absent
# after
qlib.init(provider_uri=cfg.get('provider_uri', '~/.qlib/qlib_data/cn_data')) Defensive patterns
Strategy: validation
Validate before calling
if provider_uri is None:
raise ValueError('provider_uri is required — set it to a data path such as ~/.qlib/qlib_data/cn_data') Type guard
def is_valid_provider_uri(u) -> bool:
return u is not None Prevention
- Never pass provider_uri=cfg.get('provider_uri') without a default.
- Fail fast in your own bootstrap code when required config keys are absent.
When it happens
Trigger: qlib.init(provider_uri=None) or omitting provider_uri while some code path still constructs DataPathManager; building QlibConfig programmatically and passing a None obtained from config.get('provider_uri').
Common situations: Config templating where provider_uri is conditionally set and resolves to None; refactoring that reads the key with .get() before validating presence; upgrading qlib versions where None was previously tolerated until data load time.
Related errors
- Invalid Qlib configuration (note: the global config has alre
- provider_uri does not support {type(provider_uri)}
- This type of uri is not supported
- freq(={freq}) missing group(={_gp})
- Both default_exp_name and exp_name are None. OnlineToolR nee
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/605078211a753bc1.
Report an issue: GitHub.