{"record":{"id":"b060ddfe10e5e0b9","repo":"datawhalechina/hello-agents","slug":"domain","errorCode":null,"errorMessage":"学习计划不存在：{domain}","messagePattern":"学习计划不存在：(.+?)","errorType":"exception","errorClass":"FileNotFoundError","httpStatus":null,"severity":"warning","filePath":"Co-creation-projects/Yixiang-Wu-LearningAgent/core/file_manager.py","lineNumber":114,"sourceCode":"\n        return session_path\n\n    def read_plan(self, domain: str) -> str:\n        \"\"\"\n        读取学习计划\n\n        Args:\n            domain: 领域名称\n\n        Returns:\n            计划内容\n\n        Raises:\n            FileNotFoundError: 如果计划不存在\n        \"\"\"\n        plan_path = self.BASE_DIR / domain / \"plan.md\"\n        if not plan_path.exists():\n            raise FileNotFoundError(f\"学习计划不存在：{domain}\")\n\n        try:\n            return plan_path.read_text(encoding=\"utf-8\")\n        except Exception as e:\n            raise FileReadError(f\"无法读取学习计划：{e}\")\n\n    def domain_exists(self, domain: str) -> bool:\n        \"\"\"\n        检查领域是否存在\n\n        Args:\n            domain: 领域名称\n\n        Returns:\n            是否存在\n        \"\"\"\n        return (self.BASE_DIR / domain).exists()\n","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/datawhalechina/hello-agents/blob/606a07d341a47be773fab7f4b71177f53f96b2c3/Co-creation-projects/Yixiang-Wu-LearningAgent/core/file_manager.py#L96-L132","documentation":"Standard FileNotFoundError raised by FileManager.read_plan when BASE_DIR/<domain>/plan.md does not exist on disk. It is a guard before any I/O: the file simply was never saved (or was saved under a different domain name), so there is nothing to read.","triggerScenarios":"Calling read_plan(domain) before save_plan was ever called for that domain; domain string mismatch (case differences, leading/trailing whitespace, different naming between save and read); the workspace/BASE_DIR was deleted or reset; running from a different working directory so BASE_DIR resolves elsewhere.","commonSituations":"Fresh clone with empty learning workspace; agent resumed a session with a slightly different domain label; tests that read without first writing; BASE_DIR relative path resolving differently between launch contexts.","solutions":["Call save_plan (or an initializer that creates plan.md) before read_plan for a new domain","Normalize the domain string (strip + casefold consistently) everywhere it is used as a key","Check domain_exists(domain) before reading and surface a friendly 'create plan first' flow","Pin BASE_DIR to an absolute path so the working directory cannot change resolution"],"exampleFix":"# before\nplan_path = self.BASE_DIR / domain / \"plan.md\"\nif not plan_path.exists():\n    raise FileNotFoundError(f\"学习计划不存在：{domain}\")\n\n# after\nplan_path = self.BASE_DIR / domain.strip().lower() / \"plan.md\"\nif not plan_path.exists():\n    raise FileNotFoundError(\n        f\"学习计划不存在：{domain}（已存在的领域: \"\n        f\"{[p.name for p in self.BASE_DIR.iterdir() if p.is_dir()]}）\"\n    )","handlingStrategy":"validation","validationCode":"if not fm.domain_exists(domain):\n    # no domain -> nothing was ever saved; create plan first\n    fm.save_plan(domain, default_plan(domain))\nplan = fm.read_plan(domain)","typeGuard":null,"tryCatchPattern":"try:\n    plan = fm.read_plan(domain)\nexcept FileNotFoundError:\n    plan = default_plan(domain)  # or prompt user to create one\n    fm.save_plan(domain, plan)","preventionTips":["Canonicalize the domain key (strip().lower()) in one helper and use it for both save and read","Check domain_exists() before read_plan and branch to a creation flow","Keep BASE_DIR absolute so different working directories cannot split the state"],"tags":["filesystem","not-found","python","state-management","learning-agent"],"backgroundTag":null,"analyzedSha":"606a07d341a47be773fab7f4b71177f53f96b2c3","analyzedAt":"2026-08-14T22:57:27.446Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}