Skip to content

[BUG]: UTF-8 BOM makes a valid SKILL.md fail schema while unicode calls the BOM benign #91

Description

@mimran-khan

What happened?

Windows Notepad and several editors write UTF-8 BOM. Schema reads SKILL.md as utf-8 (not utf-8-sig) and matches frontmatter with ^---:

FRONTMATTER_PATTERN = re.compile(
    r"^---[^\S\r\n]*\r?\n(.*?)\r?\n---[^\S\r\n]*(?=\r?\n|\Z)(?:\r?\n)?(.*)",
    re.DOTALL,
)

in frontmatter_parser.py. A BOM makes the file start with \ufeff---, the match fails, and schema emits HIGH SKILL.md must have YAML frontmatter between --- markers (schema.py).

The unicode check on the same file reports INFO UTF-8 BOM marker at file start (benign) (unicode_smuggle.py).

Expected: a valid SKILL.md that only differs by a leading BOM still parses. If BOM is truly benign, schema should strip it. If BOM is blocking, unicode should not call it harmless.

Actual: validate --checks schema,unicode fails schema HIGH and passes unicode with an INFO "benign" note. Same file, two opposite stories. Plugin manifests already use utf-8-sig in this repo.

Reproduction steps

tmp=$(mktemp -d)
python3 - <<PY
from pathlib import Path
p = Path("$tmp/bom")
p.mkdir()
body = """---
name: bom
description: Valid skill whose SKILL.md starts with a UTF-8 BOM.
---
# BOM skill
"""
(p / "SKILL.md").write_bytes(b"\xef\xbb\xbf" + body.encode("utf-8"))
PY

skillevaluator validate "$tmp/bom" --checks schema,unicode --no-dedup -r cli

Observed:

  • Schema: FAIL, frontmatter_format, HIGH, "must have YAML frontmatter between --- markers"
  • Unicode: PASS, bom_marker, INFO, "UTF-8 BOM marker at file start (benign)"
  • overall exit 1

Write the same bytes without the BOM and both checks pass.

SkillEvaluator version or commit

009aa300be7925c7ba75760592baeb941cc29ba8 (0.2.1)

Environment

  • macOS 15, arm64
  • Python 3.12.2
  • uv sync --python 3.12 --all-extras
  • No API key

Before submitting

Happy to send a PR that reads skill manifests with utf-8-sig (same as the plugin path) so a BOM does not break frontmatter, if that is acceptable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions