microsoft/qlib · error · ModuleNotFoundError
None is passed in as parameters as module_path
Error message
None is passed in as parameters as module_path
What it means
qlib.utils.mod.get_module_by_module_path loads a module from a filesystem path (.py), a dotted module path, or a ModuleType. Passing None is treated as a programming/configuration mistake and raises ModuleNotFoundError immediately rather than failing obscurely inside importlib. Note: this is raised via raise, so it propagates even though ModuleNotFoundError normally signals a missing package.
Source
Thrown at qlib/utils/mod.py:33
import re
import sys
from types import ModuleType
from typing import Any, Dict, List, Tuple, Union
from urllib.parse import urlparse
from qlib.typehint import InstConf
from qlib.utils.pickle_utils import restricted_pickle_load
def get_module_by_module_path(module_path: Union[str, ModuleType]):
"""Load module path
:param module_path:
:return:
:raises: ModuleNotFoundError
"""
if module_path is None:
raise ModuleNotFoundError("None is passed in as parameters as module_path")
if isinstance(module_path, ModuleType):
module = module_path
else:
if module_path.endswith(".py"):
module_name = re.sub("^[^a-zA-Z_]+", "", re.sub("[^0-9a-zA-Z_]", "", module_path[:-3].replace("/", "_")))
module_spec = importlib.util.spec_from_file_location(module_name, module_path)
module = importlib.util.module_from_spec(module_spec)
sys.modules[module_name] = module
module_spec.loader.exec_module(module)
else:
module = importlib.import_module(module_path)
return module
def split_module_path(module_path: str) -> Tuple[str, str]:
"""
View on GitHub (pinned to 79633dd950)
Solutions
- Remove the module_path key entirely (qlib then falls back to default_module) or set it to a real dotted path / .py file path.
- In config-building code, use config.pop('module_path', None) only when the value is truthy, or filter out None values before calling init_instance_by_config.
- If a string class name is used, put the full path 'a.b.c.ClassName' in the config string so split_module_path handles it.
Example fix
// before
conf = {'class': 'TopkDropoutStrategy', 'module_path': None}
inst = init_instance_by_config(conf)
// after
conf = {'class': 'TopkDropoutStrategy', 'module_path': 'qlib.contrib.strategy'}
inst = init_instance_by_config(conf) Defensive patterns
Strategy: validation
Validate before calling
conf = {k: v for k, v in conf.items() if v is not None} # drop null module_path
inst = init_instance_by_config(conf) Type guard
def is_valid_module_path(mp) -> bool:
return mp is None is False and (isinstance(mp, str) and len(mp) > 0) Try / catch
try:
inst = init_instance_by_config(conf)
except ModuleNotFoundError as e:
if 'None is passed' in str(e):
conf.pop('module_path', None)
inst = init_instance_by_config(conf)
else:
raise Prevention
- Never write `module_path: null` in workflow YAML — omit the key to use the default module.
- Sanitize configs by filtering None values before init_instance_by_config.
When it happens
Trigger: init_instance_by_config({'class': 'MyHandler', 'module_path': None}) or get_callable_kwargs where a config dict's 'module_path' key exists but its value is None; dynamically built configs where a template left module_path unset.
Common situations: YAML/JSON workflow configs (e.g. qlib task or workflow configs) with an explicit `module_path: null`; code that reads module_path with config.get('module_path') instead of omitting the key; conditional config assembly that assigns None on a missing branch.
Related errors
- This type of input is not supported
- method {method} is not supported!
- This type of input {rtype} is not supported
- Can't find the BASE_CONFIG file: {base_config_path}
- Invalid Qlib configuration (note: the global config has alre
AI-assisted analysis of microsoft/qlib@79633dd950 (2026-08-15).
Data as JSON: /api/errors/4cde1a4f05bac522.
Report an issue: GitHub.