deepset-ai/haystack · error · ValueError
Skill frontmatter is opened with '---' but never closed with
Error message
Skill frontmatter is opened with '---' but never closed with a matching '---' line.
What it means
Skill files use YAML frontmatter delimited by two `---` lines. _parse_frontmatter finds the opening `---` on the first line but no closing line containing exactly `---`, so it raises ValueError because the frontmatter block is unterminated and the skill metadata cannot be parsed.
Source
Thrown at haystack/skill_stores/file_system/skill_store.py:44
Split a `SKILL.md` file into its YAML frontmatter and markdown body.
The frontmatter is the YAML block delimited by a leading and a trailing line containing exactly `---`.
If the first line is not `---`, no frontmatter is present and an empty mapping and the original text
are returned.
:param text: The full contents of a `SKILL.md` file.
:returns: A tuple of (frontmatter mapping, body).
:raises ValueError: If the frontmatter is opened with `---` but never closed, is not valid YAML, or is
not a YAML mapping.
"""
lines = text.lstrip().split("\n")
if lines[0].rstrip() != "---":
return {}, text
# Find the closing delimiter: the next line containing exactly '---'.
closing_index = next((i for i, line in enumerate(lines[1:], start=1) if line.rstrip() == "---"), None)
if closing_index is None:
raise ValueError("Skill frontmatter is opened with '---' but never closed with a matching '---' line.")
frontmatter_block = "\n".join(lines[1:closing_index])
body = "\n".join(lines[closing_index + 1 :])
try:
loaded = yaml.safe_load(frontmatter_block) or {}
except yaml.YAMLError as e:
raise ValueError(f"Skill frontmatter is not valid YAML: {e}") from e
if not isinstance(loaded, dict):
raise ValueError("Skill frontmatter must be a YAML mapping.") # noqa: TRY004
return loaded, body.lstrip("\n")
class FileSystemSkillStore:
"""
SkillStore backed by a directory of skill sub-directories on the local filesystem.
Expected layout:
View on GitHub (pinned to e318778c9b)
Solutions
- Add a closing line containing exactly `---` after the frontmatter key/value block
- Ensure the closing delimiter is on its own line with no leading/trailing spaces (line.rstrip() == "---")
- Validate the whole frontmatter block parses as YAML (the next check after this one)
Example fix
// before --- name: my-skill description: Does things # file ends without closing delimiter // after --- name: my-skill description: Does things ---
Defensive patterns
Strategy: validation
Validate before calling
lines = text.splitlines()
if lines and lines[0].rstrip() == "---":
assert any(l.rstrip() == "---" for l in lines[1:]), "frontmatter never closed with '---'" Type guard
def has_closed_frontmatter(text: str) -> bool:
lines = text.splitlines()
if not lines or lines[0].rstrip() != "---":
return True # no frontmatter, not an error
return any(l.rstrip() == "---" for l in lines[1:]) Try / catch
try:
meta, body = store.load_skill(name)
except ValueError as e:
if "never closed" in str(e):
text = text.rstrip() + "\n---\n" # repair missing closing delimiter
meta, body = parse_frontmatter(text)
else:
raise Prevention
- Always end frontmatter with a line containing exactly `---`
- Lint skill files for balanced frontmatter delimiters in CI
- Avoid editors/templates that strip trailing delimiter lines
When it happens
Trigger: Loading a skill whose file starts with `---` but lacks a matching closing `---` line — e.g. truncated file, the closing delimiter accidentally indented or written as `----` or `-- -`, or content merged that swallowed the delimiter.
Common situations: Hand-authored skill files with missing final `---`; editors or copy-paste stripping trailing delimiter lines; template generation bugs that emit the opening fence but not the closing one.
Related errors
- Invalid hook point '{hook_point}'. Valid hook points are: {'
- Hook registered for hook point '{hook_point}' is callable bu
- CSVToDocument(row): could not parse CSV rows for {source}: {
- Error dumping pipeline to YAML - Ensure that all pipeline co
- Error loading pipeline from YAML - Ensure that all pipeline
AI-assisted analysis of deepset-ai/haystack@e318778c9b (2026-08-30).
Data as JSON: /api/errors/877a2b906f802e2e.
Report an issue: GitHub.