Claude Code に MDX の記事生成を任せ始めると、最初の数十本は問題なく通るのに、ある日突然 npm run build が YAMLException: end of the stream or a document separator is expected のような不可解なメッセージで止まります。本文をいくら見直してもエラーが消えず、原因がフロントマターのほうにあると気付くまでに半日溶かしました。
私自身、Dolice Labs の4サイト(Claude Lab・Gemini Lab・Antigravity Lab・Rork Lab)で1日16本の記事を Claude Code 起点で自動生成する運用を組んだ直後、まさにこのパターンで Cloudflare のビルドが立て続けに 3 件落ちました。2014年からアプリ事業(AdMob 中心の累計5,000万DL)を個人開発してきて「環境差で動かない」系のトラブルには慣れていたつもりですが、YAML パーサの挙動だけは Claude が悪気なく踏み抜いてくれます。
症状 — ビルドが「YAML パース失敗」で止まる
Next.js + MDX + gray-matter 系の構成だと、ビルド時にこういうメッセージが出ます。
[Error: YAMLException: can not read a block mapping entry; a multiline key may not be an implicit key
at line 4, column 1:
description: "Claude Code を「Plan モード」で起動すると…"
^]
または unexpected end of the stream、tag suffix cannot contain flow indicator characters のような表現で出ることもあります。エディタ上では何も問題なく見えるので「Cloudflare 側のビルダがおかしいのでは」と疑ってしまいますが、ほとんどの場合はフロントマターの値の中に YAML パーサが解釈し損なう文字列 が混入しているだけです。
再現条件 — Claude が踏みやすい3パターン
実運用で繰り返し踏んだのは以下の3つです。Claude Code は意味的に正しい日本語を書こうとして引用符を多用するので、この手の事故が起きやすいです。
パターン 1: ダブルクォートで囲んだ値の内側にダブルクォートが入る
description: "Claude Code を "Plan モード" で起動すると…"これは構文的に「Claude Code を 」までが値で、その後の Plan モード は別のキーだと解釈されます。ダブルクォートを文字として扱いたい場合はエスケープが必要なのですが、Claude は普通の日本語の流れで意識せずに入れてきます。
パターン 2: 値の途中に裸のコロン + 半角スペース
title: "Claude Code 3.0 リリース: 新機能まとめ"クォートで囲んでいるので一見大丈夫そうですが、後段の処理系(特に js-yaml の strict モード)で key: value の塊と誤読されることがあります。実害が出るのは「クォートを外したまま title: 3.0: 新機能 のように書いた場合」が多いですが、長い description でクォートが正しく閉じていないと連鎖して爆発します。
パターン 3: タグ配列の中にカンマやコロン
tags: ["Claude Code, Cowork", "TypeScript"]これは YAML 的には正しいのですが、人間が「Claude Code と Cowork」を1要素として書きたかったのに、後段の tags.includes("Claude Code") で永遠にヒットしなくなるという別種のバグになります。エラーは出ないので余計にタチが悪いです。
原因 — YAML パーサはダブルクォート内のダブルクォートを終端と見なす
YAML 1.2 の仕様では、ダブルクォート文字列は C 言語スタイルのエスケープが必須 です。" をリテラルとして含めたければ \" と書く必要があります。一方、シングルクォート文字列は内側の ' を ''(二重シングル)で表現する仕様で、それ以外の特殊文字は意識せず書けます。
Claude Code が出力する文字列は LLM が自然言語で組み立てたものなので、エスケープ規則を踏まえずに 「」 のような感覚で "..." を放り込んでしまうことがあります。Claude 自身は「フロントマターは YAML だから引用符は気をつけて」と言えば直してくれるのですが、毎記事プロンプトでそれを言うのは現実的ではありません。
対処 — 実運用で安定した5つの書き方
私が Dolice Labs で実際に採用して落ち着いたのが以下のパターンです。安定度の高い順に並べました。
対処 1: 日本語の引用は鉤括弧「」に置換させる
最も確実なのはこれです。SKILL.md やシステムプロンプトに「フロントマターの中で引用符を使う必要があるときは、必ず「」(全角鉤括弧)に置換すること」と明記しておきます。日本語記事なら見た目もむしろ自然になります。
description: "Claude Code を「Plan モード」で起動すると安全に検証できます"対処 2: 英数字の引用はシングルクォートで全体を囲む
英数字のダブルクォートを残したい場合は、外側をシングルクォートに切り替えます。
description: 'Use Claude Code in "Plan mode" before applying changes'シングルクォート内に ' を含めたいときは '' と書きます。日英両方の記事を持つサイトでは「日本語版は鉤括弧、英語版はシングルクォート外側」というルールに揃えるとブレません。
対処 3: ブロックスカラー(| または >)にする
長い説明文や、複数の引用が混ざる文章では、ブロックスカラー記法が一番ラクです。
description: >
Claude Code を "Plan モード" で起動すると、変更計画を
ドライランで確認できます。「Edit ツールは破壊的」と
公式ドキュメントが繰り返し警告するのはこのためです。> は改行をスペースに畳み込み、| は改行を保持します。description は1行のほうが OGP の都合がよいので、私は > 派です。
対処 4: 半角コロン + 半角スペースを避ける
タイトルや description でコロンを使うときは、「:」(全角コロン)か、-(ハイフン)で代用すると後段処理のリスクが消えます。
# 避ける
title: "Claude Code 3.0: 新機能まとめ"
# 推奨
title: "Claude Code 3.0 — 新機能まとめ"対処 5: タグ配列はカンマを含めない
タグは1要素に1概念を入れる規則を徹底します。「Claude Code, Cowork」のような複合タグは作らず、別タグに分けるかフィルタ側で OR 条件にします。
tags: ["Claude Code", "Cowork", "TypeScript"]予防 — push 直前に1行で検証する
Dolice Labs では、すべての MDX を push する前に Python の pyyaml でフロントマターだけ抜き出して yaml.safe_load にかけ、例外が出たら push を中断するスクリプトを挟んでいます。本体の Next.js ビルドを待つより圧倒的に早く落ちるので、Cloudflare の無駄なビルドキューを生まずに済みます。
import re
import sys
import yaml
from pathlib import Path
def check(path):
text = Path(path).read_text(encoding="utf-8")
m = re.match(r"^---\n(.*?)\n---\n", text, re.DOTALL)
if not m:
return f"{path}: no frontmatter"
try:
yaml.safe_load(m.group(1))
except yaml.YAMLError as e:
return f"{path}: {e}"
return None
errors = [e for e in (check(p) for p in sys.argv[1:]) if e]
if errors:
print("\n".join(errors))
sys.exit(1)bash から python3 yaml_check.py content/articles/**/*.mdx のように呼び出します。yaml.safe_load が落ちた瞬間に行番号付きでメッセージが出るので、原因の特定も Cloudflare のログを待つより早いです。
「Claude が悪い」のではなく「人間側で線を引く」発想で
Claude Code のフロントマター事故に何度かやられて私が学んだのは、LLM に YAML のエスケープ規則を完璧に守らせるより、人間側で「使ってよい文字」を狭くしたほうが速い ということです。鉤括弧に統一する、コロンは全角にする、タグはカンマを含めない — このルールを SKILL.md に書いて、push 直前で機械検証します。それだけで個人開発の量産パイプラインは劇的に安定します。
同じ仕組みでブログを4つ並行運用していますが、ルールを入れた後はフロントマター起因の Cloudflare ビルド失敗は起きていません。お読みいただきありがとうございました。