datawhalechina/hello-agents · error · ValueError
无效的笔记格式:缺少YAML前置元数据
Error message
无效的笔记格式:缺少YAML前置元数据
What it means
ValueError from NoteTool._markdown_to_note when the markdown text does not begin with a '---\n...\n---\n' YAML frontmatter block (regex re.match with DOTALL anchors at position 0). Every stored note is round-tripped as frontmatter + body, so text lacking the leading delimiters cannot be parsed back into a note object.
Source
Thrown at Co-creation-projects/YYHDBL-HelloCodeAgentCli/tools/builtin/note_tool.py:154
tags_str = json.dumps(note['tags'])
frontmatter += f"tags: {tags_str}\n"
frontmatter += f"created_at: {note['created_at']}\n"
frontmatter += f"updated_at: {note['updated_at']}\n"
frontmatter += "---\n\n"
# Markdown内容
content = f"# {note['title']}\n\n"
content += note['content']
return frontmatter + content
def _markdown_to_note(self, markdown_text: str) -> Dict[str, Any]:
"""将Markdown文本解析为笔记对象"""
# 提取YAML前置元数据
frontmatter_match = re.match(r'^---\s*\n(.*?)\n---\s*\n', markdown_text, re.DOTALL)
if not frontmatter_match:
raise ValueError("无效的笔记格式:缺少YAML前置元数据")
frontmatter_text = frontmatter_match.group(1)
content_start = frontmatter_match.end()
# 解析YAML(简化版)
note = {}
for line in frontmatter_text.split('\n'):
if ':' in line:
key, value = line.split(':', 1)
key = key.strip()
value = value.strip()
# 处理特殊字段
if key == 'tags':
try:
note[key] = json.loads(value)
except:
note[key] = []View on GitHub (pinned to 606a07d341)
Solutions
- Ensure the note file starts, on line 1, with '---', then YAML keys, then a closing '---' before the body.
- Strip leading whitespace/BOM before parsing: markdown_text.lstrip('\ufeff').lstrip().
- If reading foreign markdown, skip note parsing or synthesize frontmatter (title/date) first.
Example fix
# before (parse fails) text = '# My Note\n\nbody...' note = tool._markdown_to_note(text) # after text = '---\ntitle: My Note\ncreated: 2026-01-01\n---\n\n# My Note\n\nbody...' note = tool._markdown_to_note(text)
Defensive patterns
Strategy: try-catch
Validate before calling
def has_frontmatter(md: str) -> bool:
return bool(re.match(r'^---\s*\n.*?\n---\s*(\n|$)', md, re.DOTALL))
if not has_frontmatter(text):
text = f'---\ntitle: untitled\n---\n\n{text}' # or reject Type guard
def is_note_markdown(md: str) -> bool:
first = md.lstrip('\ufeff').splitlines()[0] if md.strip() else ''
return first.strip() == '---' Try / catch
try:
note = tool._markdown_to_note(md)
except ValueError as e:
if 'YAML' in str(e):
md = f'---\ntitle: imported\n---\n\n{md}'
note = tool._markdown_to_note(md)
else:
raise Prevention
- Always write notes through the tool so frontmatter is generated.
- Keep '---' as the literal first line; no leading blank lines or BOM.
- Validate imported markdown before parsing.
When it happens
Trigger: Calling the note tool's parse/read path with plain markdown that has no frontmatter; a leading blank line or BOM before the first '---' so re.match fails; frontmatter delimiters using '----' or missing the closing '---'.
Common situations: Users pasting raw markdown into a note-read/list operation; hand-edited note files where the frontmatter was deleted; files created by other tools (Obsidian requires exact '---' first line too); trailing spaces after '---' are tolerated by \s* but a preceding empty line is not.
Related errors
- 无法从输出解析 note_id: {output}
- Error '{repr(e)}' occurred while parsing the theorem '{theor
- Patch must start with '*** Begin Patch'
- Patch must end with '*** End Patch'
- Unexpected patch line: {line}
AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14).
Data as JSON: /api/errors/2519fcbb22340cd1.
Report an issue: GitHub.