datawhalechina/hello-agents · error · FileWriteError
无法保存知识笔记:{e}
Error message
无法保存知识笔记:{e} What it means
FileWriteError raised by FileManager.save_knowledge when writing a knowledge note to BASE_DIR/<domain>/knowledge/<filename> fails. write_text does not create intermediate directories, so a missing knowledge/ subdirectory is the dominant trigger. The bare except Exception also swallows the traceback unless re-raised with `from e`.
Source
Thrown at Co-creation-projects/Yixiang-Wu-LearningAgent/core/file_manager.py:75
try:
plan_path.write_text(plan_content, encoding="utf-8")
except Exception as e:
raise FileWriteError(f"无法保存学习计划:{e}")
def save_knowledge(self, domain: str, filename: str, content: str) -> None:
"""
保存知识笔记
Args:
domain: 领域名称
filename: 文件名
content: 文件内容
"""
knowledge_path = self.BASE_DIR / domain / "knowledge" / filename
try:
knowledge_path.write_text(content, encoding="utf-8")
except Exception as e:
raise FileWriteError(f"无法保存知识笔记:{e}")
def save_session(self, domain: str, session_content: str) -> Path:
"""
保存单次学习会话记录
Args:
domain: 领域名称
session_content: 会话内容
Returns:
保存的文件路径
"""
date = datetime.now().strftime("%Y-%m-%d")
time = datetime.now().strftime("%H-%M")
session_path = self.BASE_DIR / domain / "sessions" / f"session_{date}_{time}.md"
try:
session_path.write_text(session_content, encoding="utf-8")View on GitHub (pinned to 606a07d341)
Solutions
- mkdir the knowledge dir first: knowledge_path.parent.mkdir(parents=True, exist_ok=True)
- Validate filename: reject empty strings, '/' and '..' components to prevent path traversal
- Fix directory permissions/ownership on BASE_DIR and descendants
- Chain the original exception with `raise ... from e` to preserve the traceback
Example fix
# before
knowledge_path = self.BASE_DIR / domain / "knowledge" / filename
try:
knowledge_path.write_text(content, encoding="utf-8")
except Exception as e:
raise FileWriteError(f"无法保存知识笔记:{e}")
# after
if not filename or '/' in filename or filename in {'.', '..'}:
raise ValueError(f"非法笔记文件名: {filename!r}")
knowledge_path = self.BASE_DIR / domain / "knowledge" / filename
try:
knowledge_path.parent.mkdir(parents=True, exist_ok=True)
knowledge_path.write_text(content, encoding="utf-8")
except OSError as e:
raise FileWriteError(f"无法保存知识笔记 {knowledge_path}: {e}") from e Defensive patterns
Strategy: validation
Validate before calling
import re
SAFE_FILENAME = re.compile(r"^[\w\-]+\.(md|txt)$")
def valid_knowledge_filename(filename: str) -> bool:
return bool(filename) and bool(SAFE_FILENAME.match(filename)) Type guard
def is_safe_filename(name: str) -> bool:
return (
isinstance(name, str)
and name not in ('.', '..')
and '/' not in name
and '\\' not in name
and name.strip() != ''
) Try / catch
try:
fm.save_knowledge(domain, filename, content)
except FileWriteError as e:
logger.error("knowledge save failed: %s/%s: %s", domain, filename, e) Prevention
- Whitelist filename patterns (markdown extensions only) before calling save_knowledge
- Never pass LLM-generated filenames through unchecked — sanitize or derive them from a slug + timestamp
- Create knowledge/ at domain initialization time, not lazily at first write
When it happens
Trigger: Calling save_knowledge before BASE_DIR/<domain>/knowledge/ exists; filename containing '/' causing an unexpected nested path or escape outside knowledge/; permission errors on the knowledge directory; filename being empty or '.' so the path resolves to a directory; disk full.
Common situations: Agent writes its first note for a newly created domain that only has plan.md; LLM-generated filename with slashes or Windows-style separators; read-only mount in production.
Related errors
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/dfe82586286472cd.
Report an issue: GitHub.