{"record":{"id":"6aacea145a764803","repo":"microsoft/qlib","slug":"we-can-t-find-the-project-path","errorCode":null,"errorMessage":"We can't find the project path","messagePattern":"We can't find the project path","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"warning","filePath":"qlib/__init__.py","lineNumber":239,"sourceCode":"        NOTE: link is not supported here.\n\n\n    This method is often used when\n    - user want to use a relative config path instead of hard-coding qlib config path in code\n\n    Raises\n    ------\n    FileNotFoundError:\n        If project path is not found\n    \"\"\"\n    if cur_path is None:\n        cur_path = Path(__file__).absolute().resolve()\n    cur_path = Path(cur_path)\n    while True:\n        if (cur_path / config_name).exists():\n            return cur_path\n        if cur_path == cur_path.parent:\n            raise FileNotFoundError(\"We can't find the project path\")\n        cur_path = cur_path.parent\n\n\ndef auto_init(**kwargs):\n    \"\"\"\n    This function will init qlib automatically with following priority\n    - Find the project configuration and init qlib\n        - The parsing process will be affected by the `conf_type` of the configuration file\n    - Init qlib with default config\n    - Skip initialization if already initialized\n\n    :**kwargs: it may contain following parameters\n                cur_path: the start path to find the project path\n\n    Here are two examples of the configuration\n\n    Example 1)\n    If you want to create a new project-specific config based on a shared configure, you can use  `conf_type: ref`","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/microsoft/qlib/blob/79633dd9506ea689e5400dea0197717b5b3d74b7/qlib/__init__.py#L221-L257","documentation":"DatasetCache._dataset (qlib/data/cache.py:432) is the abstract method that reads a cached feature dataset. The base raises NotImplementedError, but the public dataset() wrapper catches it and delegates to self.provider.dataset(...) — so data loading still succeeds, just uncached, whenever the subclass (or base) lacks a real _dataset implementation.","triggerScenarios":"Registering a DatasetCache subclass without overriding _dataset: D.features(...) works but never hits a dataset cache; calling _dataset directly always raises; commonly co-occurs with error at cache.py:423 because _uri is also unimplemented and has no fallback.","commonSituations":"Custom dataset cache classes where only constructor/init changed; misconfiguring dataset_cache to the abstract base instead of DiskDatasetCache.","solutions":["Use DiskDatasetCache (file-backed), or SimpleDatasetCache/DatasetURICache as appropriate","Override _dataset(self, instruments, fields, start_time=None, end_time=None, freq='day', disk_cache=1, inst_processors=[]) -> pd.DataFrame to read your backend","Verify the override signature matches exactly, including inst_processors"],"exampleFix":"# before\nqlib.init(dataset_cache=DatasetCache)  # abstract; silent no-cache fallback\n\n# after\nfrom qlib.data.cache import DiskDatasetCache\nqlib.init(dataset_cache=DiskDatasetCache)","handlingStrategy":"fallback","validationCode":"from qlib.data.cache import DatasetCache\n\nif MyDSCache._dataset is DatasetCache._dataset:\n    print(\"WARNING: dataset cache disabled (falls back to provider)\")","typeGuard":null,"tryCatchPattern":"# dataset() already falls back to provider.dataset on NotImplementedError;\n# verify caching actually happens by checking cache dir size after runs","preventionTips":["Watch for flat cache-dir growth — it signals silent fallback","Use DiskDatasetCache unless a custom backend is required","Match override signatures exactly (inst_processors included)"],"tags":["qlib","cache","custom-backend","not-implemented"],"backgroundTag":null,"analyzedSha":"79633dd9506ea689e5400dea0197717b5b3d74b7","analyzedAt":"2026-08-15T07:01:27.511Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}