Summary
22 of the translated skill docs under docs/{locale}/skills/ carry a frontmatter block that fails yaml.safe_load. The English originals under skills/ are all fine — the defects were introduced by the translation pass, and each one is mechanical.
Measured on 0e88e6a (docs: refresh zero queue dashboard): 827 SKILL.md in the repo, 22 invalid, all under docs/.
import re, yaml, pathlib
bad = []
for f in pathlib.Path('.').rglob('SKILL.md'):
m = re.match(r'^---\n(.*?)\n---\n', f.read_text(errors='replace'), re.S)
if not m:
bad.append((f, 'no frontmatter')); continue
try:
yaml.safe_load(m.group(1))
except Exception as e:
bad.append((f, str(e).split('\n')[0]))
print(len(bad)) # 22
Four distinct defects
1. Following key glued onto the description line (12 files)
The newline between the end of description and the next key was lost, so the key became part of the description text:
description: …退货欺诈检测或保修索赔时使用。license: Apache-2.0
version: 1.0.0
yaml.safe_load → mapping values are not allowed here. The glued key is license: Apache-2.0 in 9 files and origin: community in 3, and those keys are silently lost even by a lenient parser.
docs/ja-JP/skills/returns-reverse-logistics/SKILL.md
docs/ja-JP/skills/token-budget-advisor/SKILL.md
docs/zh-CN/skills/blueprint/SKILL.md
docs/zh-CN/skills/carrier-relationship-management/SKILL.md
docs/zh-CN/skills/customs-trade-compliance/SKILL.md
docs/zh-CN/skills/energy-procurement/SKILL.md
docs/zh-CN/skills/inventory-demand-planning/SKILL.md
docs/zh-CN/skills/logistics-exception-management/SKILL.md
docs/zh-CN/skills/production-scheduling/SKILL.md
docs/zh-CN/skills/quality-nonconformance/SKILL.md
docs/zh-CN/skills/returns-reverse-logistics/SKILL.md
docs/zh-CN/skills/token-budget-advisor/SKILL.md
2. Quotes dropped from a description containing a colon (4 files)
The English original quotes the value precisely because it embeds : :
# skills/django-verification/SKILL.md — valid
description: "Verification loop for Django projects: migrations, linting, tests with coverage, …"
# docs/ja-JP/skills/django-verification/SKILL.md — invalid
description: Verification loop for Django projects: migrations, linting, tests with coverage, …
(These four descriptions were also left untranslated, which may be worth a separate look.)
docs/ja-JP/skills/django-verification/SKILL.md
docs/ja-JP/skills/springboot-verification/SKILL.md
docs/tr/skills/laravel-verification/SKILL.md
docs/zh-CN/skills/laravel-verification/SKILL.md
3. Description opens with the reserved @ indicator (1 file)
description: @Observableを使用した状態管理、ビュー合成、…
→ found character '@' that cannot start any token. The English original starts with SwiftUI architecture patterns, state management with @Observable, …, so the reordering during translation moved @ into the first column, where YAML treats it as a reserved indicator.
docs/ja-JP/skills/swiftui-patterns/SKILL.md
4. No frontmatter block at all (5 files)
The file starts directly on the translated # heading; name and description are simply absent.
docs/ja-JP/skills/project-guidelines-example/SKILL.md
docs/ja-JP/skills/verification-loop/SKILL.md
docs/zh-CN/skills/browser-qa/SKILL.md
docs/zh-TW/skills/project-guidelines-example/SKILL.md
docs/zh-TW/skills/verification-loop/SKILL.md
Impact
These paths are documentation, not skills loaded by Claude Code (the loader reads skills/, and all 249 there are valid), so nothing breaks at runtime today. It does matter for anything that walks the repo and parses skill frontmatter — the stocktake/scanner tooling discussed in #2598, translation-drift checks, or downstream consumers that mirror the localized skill directories into a real skill directory. Defect 1 also drops real metadata (license, version, origin) from 12 skills.
Suggested fix
All four are mechanical:
- reinsert the newline before the absorbed key;
- restore the quoting the English original already uses;
- quote the value that starts with
@;
- add
name + description (recoverable from each document's own heading and intro, plus origin: ECC where the English original carries it).
A CI guard would keep it from recurring — parsing the frontmatter of every SKILL.md and asserting name and description are present is a few lines and would have caught all 22.
I have this applied locally against 0e88e6a, translated prose untouched, with all 827 files parsing afterwards. Happy to open a PR if that is useful — let me know whether you would rather regenerate the translations from source, since the root cause looks like it lives in the translation pipeline rather than in these files.
Edited to fix a miscount in defect 1 (12 files, not 11 — origin: community accounts for 3, not 2) and a docs/{locale}/… path that rendered as an empty HTML tag.
Summary
22 of the translated skill docs under
docs/{locale}/skills/carry a frontmatter block that failsyaml.safe_load. The English originals underskills/are all fine — the defects were introduced by the translation pass, and each one is mechanical.Measured on
0e88e6a(docs: refresh zero queue dashboard): 827SKILL.mdin the repo, 22 invalid, all underdocs/.Four distinct defects
1. Following key glued onto the description line (12 files)
The newline between the end of
descriptionand the next key was lost, so the key became part of the description text:yaml.safe_load→mapping values are not allowed here. The glued key islicense: Apache-2.0in 9 files andorigin: communityin 3, and those keys are silently lost even by a lenient parser.docs/ja-JP/skills/returns-reverse-logistics/SKILL.mddocs/ja-JP/skills/token-budget-advisor/SKILL.mddocs/zh-CN/skills/blueprint/SKILL.mddocs/zh-CN/skills/carrier-relationship-management/SKILL.mddocs/zh-CN/skills/customs-trade-compliance/SKILL.mddocs/zh-CN/skills/energy-procurement/SKILL.mddocs/zh-CN/skills/inventory-demand-planning/SKILL.mddocs/zh-CN/skills/logistics-exception-management/SKILL.mddocs/zh-CN/skills/production-scheduling/SKILL.mddocs/zh-CN/skills/quality-nonconformance/SKILL.mddocs/zh-CN/skills/returns-reverse-logistics/SKILL.mddocs/zh-CN/skills/token-budget-advisor/SKILL.md2. Quotes dropped from a description containing a colon (4 files)
The English original quotes the value precisely because it embeds
::(These four descriptions were also left untranslated, which may be worth a separate look.)
docs/ja-JP/skills/django-verification/SKILL.mddocs/ja-JP/skills/springboot-verification/SKILL.mddocs/tr/skills/laravel-verification/SKILL.mddocs/zh-CN/skills/laravel-verification/SKILL.md3. Description opens with the reserved
@indicator (1 file)→
found character '@' that cannot start any token. The English original starts withSwiftUI architecture patterns, state management with @Observable, …, so the reordering during translation moved@into the first column, where YAML treats it as a reserved indicator.docs/ja-JP/skills/swiftui-patterns/SKILL.md4. No frontmatter block at all (5 files)
The file starts directly on the translated
#heading;nameanddescriptionare simply absent.docs/ja-JP/skills/project-guidelines-example/SKILL.mddocs/ja-JP/skills/verification-loop/SKILL.mddocs/zh-CN/skills/browser-qa/SKILL.mddocs/zh-TW/skills/project-guidelines-example/SKILL.mddocs/zh-TW/skills/verification-loop/SKILL.mdImpact
These paths are documentation, not skills loaded by Claude Code (the loader reads
skills/, and all 249 there are valid), so nothing breaks at runtime today. It does matter for anything that walks the repo and parses skill frontmatter — the stocktake/scanner tooling discussed in #2598, translation-drift checks, or downstream consumers that mirror the localized skill directories into a real skill directory. Defect 1 also drops real metadata (license,version,origin) from 12 skills.Suggested fix
All four are mechanical:
@;name+description(recoverable from each document's own heading and intro, plusorigin: ECCwhere the English original carries it).A CI guard would keep it from recurring — parsing the frontmatter of every
SKILL.mdand assertingnameanddescriptionare present is a few lines and would have caught all 22.I have this applied locally against
0e88e6a, translated prose untouched, with all 827 files parsing afterwards. Happy to open a PR if that is useful — let me know whether you would rather regenerate the translations from source, since the root cause looks like it lives in the translation pipeline rather than in these files.Edited to fix a miscount in defect 1 (12 files, not 11 —
origin: communityaccounts for 3, not 2) and adocs/{locale}/…path that rendered as an empty HTML tag.