{"record":{"id":"8def97e78362ea4c","repo":"microsoft/qlib","slug":"invalid-qlib-configuration-note-the-global-confi","errorCode":null,"errorMessage":"Invalid Qlib configuration (note: the global config has already been updated):\nInvalid Qlib configuration:\n- {errors}","messagePattern":"Invalid Qlib configuration \\(note: the global config has already been updated\\):\nInvalid Qlib configuration:\n- (.+?)","errorType":"exception","errorClass":"ValueError","httpStatus":null,"severity":"critical","filePath":"qlib/config.py","lineNumber":82,"sourceCode":"class Config:\n    def __init__(self, default_conf):\n        self.__dict__[\"_default_config\"] = copy.deepcopy(default_conf)\n        self.reset()\n\n    # TODO: This validation logic is a temporary solution.\n    # The long-term goal is to migrate Qlib Config to a typed configuration\n    # system based on pydantic.BaseModel, with explicit schema and field validation.\n    def validate(self):\n        errors = []\n\n        if not self.get(\"provider_uri\"):\n            errors.append(\"provider_uri must be set (e.g. ~/.qlib/qlib_data or a valid path)\")\n\n        if not self.get(\"region\"):\n            errors.append(\"region must be specified (e.g. 'cn', 'us')\")\n\n        if errors:\n            raise ValueError(\n                \"Invalid Qlib configuration (note: the global config has already been updated):\\n\"\n                \"Invalid Qlib configuration:\\n- \" + \"\\n- \".join(errors)\n            )\n\n    def __getitem__(self, key):\n        return self.__dict__[\"_config\"][key]\n\n    def __getattr__(self, attr):\n        if attr in self.__dict__[\"_config\"]:\n            return self.__dict__[\"_config\"][attr]\n        raise AttributeError(f\"No such `{attr}` in self._config\")\n\n    def get(self, key, default=None):\n        return self.__dict__[\"_config\"].get(key, default)\n\n    def __setitem__(self, key, value):\n        self.__dict__[\"_config\"][key] = value\n","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/config.py#L64-L100","documentation":"qlib's global config (qlib/config.py) now validates itself after qlib.init() updates it: provider_uri must be set and region must be specified ('cn' or 'us'). If either is missing the ValueError lists all problems, and importantly the global config has ALREADY been mutated before validation fails — a subsequent init in the same process operates on partially-updated state.","triggerScenarios":"Calling qlib.init() without a provider_uri (e.g. only passing region), or constructing QlibConfig and calling validate() before region/provider_uri defaults are filled; also triggered by config updates that delete or blank these keys.","commonSituations":"Fresh setups that skip provider_uri because they intend to set a custom data provider later; programmatic init with an empty dict; version migration where older qlib silently defaulted provider_uri but the new typed-config validation rejects it.","solutions":["Always pass both keys to qlib.init: qlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region='cn').","If provider data is not ready, point provider_uri at the intended location anyway (existence is checked later by data loading, not by init).","After this error in a long-lived process, restart the process or fully reset the global config before re-initializing, since the global config was already partially updated.","Use qlib.init_from_yaml or checked example configs from the qlib repo as a template."],"exampleFix":"# before\nqlib.init(region='cn')  # provider_uri missing -> ValueError\n# after\nqlib.init(provider_uri='~/.qlib/qlib_data/cn_data', region='cn')","handlingStrategy":"validation","validationCode":"import qlib.config as cfg\nmissing = [k for k in ('provider_uri', 'region') if not cfg.get(k)]\nif missing:\n    raise ValueError(f'qlib config missing required keys: {missing}')","typeGuard":null,"tryCatchPattern":"try:\n    qlib.init(**init_kwargs)\nexcept ValueError as e:\n    if 'Invalid Qlib configuration' in str(e):\n        init_kwargs.setdefault('provider_uri', '~/.qlib/qlib_data/cn_data')\n        init_kwargs.setdefault('region', 'cn')\n        qlib.init(**init_kwargs)\n    else:\n        raise","preventionTips":["Always pass provider_uri and region to qlib.init explicitly.","Treat this error as process-fatal: the global config is already mutated, so restart rather than partially re-init.","Keep a single validated init helper function used by all entry points."],"tags":["qlib","config","init","validation"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}