Astro Content Collectionsのschemaエラーを直す―category・subcategoryの設計を見直す
AstroのContent Collection schemaに合わないFrontmatterでCloudflare Workersのビルドが失敗。categoryとsubcategoryの修正後に見つかった分類ミス、タグ重複、トップページの余白まで続けて修正した流れを記録します。

Astroの記事を追加してGitHubへpushしたあと、
「ローカルでは記事を書いただけなのに、Cloudflareのビルドが失敗した」
「InvalidContentEntryDataErrorと出るが、どこを直せばいいのか分からない」
「categoryやsubcategoryには表示名を入れてはいけないのか」
という状態になりました。
ゆまラボで実際に原因を確認すると、Content Collectionsのschemaと記事Frontmatterの値が一致していないことが原因でした。Cloudflare WorkersやWranglerは正常でした。
さらに最初のエラーを直したあとも、initial-setupと既存のsetupが別カテゴリとして扱われる問題が見つかりました。
つまり「ビルドが通る値」と「サイト内で正しく分類される値」は同じとは限りません。
この記事では、実際に発生したInvalidContentEntryDataErrorから、category・subcategoryの内部値と表示名を整理するまでの流れをまとめます。
Cloudflare Workersのビルドが失敗した#
記事を追加してpushしたあと、Cloudflare Workersのデプロイ画面を見ると最新ビルドが失敗していた。一瞬Cloudflare側の問題かと思ったが、ログを追うと違った。

ログを確認すると、依存関係のインストールまでは正常に進んでいる。
問題が出ているのはastro buildでContent Collectionsを読み込むタイミング。
InvalidContentEntryDataErrorの対象ファイルを確認する#
[InvalidContentEntryDataError]
blog → web-development/initial-setup/astro-vs-wordpress data does not match collection schema.
category: 半角英小文字・数字・ハイフンの識別子を指定してください
subcategory: 半角英小文字・数字・ハイフンの識別子を指定してください
対象ファイルも明確に出ている。
src/content/blog/web-development/initial-setup/astro-vs-wordpress.md
今回は、追加したMarkdownのFrontmatterがContent Collectionのschemaに合っていない。
原因はFrontmatterへ日本語カテゴリを入れていたこと#
追加した記事では、Frontmatterを次のようにしていた。
category: "Web制作"
subcategory: "初期構築"
画面に表示したい名前をそのままFrontmatterへ入れた形だが、現在のゆまラボではcategoryとsubcategoryに識別子を使う。
schema側も半角英小文字・数字・ハイフンを要求しているため、日本語ではビルドを通せない。
そこで一度、次のように変更した。
category: "web-development"
subcategory: "initial-setup"
記事本文や画像、slugには触れず、Frontmatterだけを修正して再度pushする。
categoryとsubcategoryを識別子へ変更する#
修正後のCloudflare Workersでは、ビルドからデプロイまで正常に完了した。

ビルド履歴でも、直前の失敗と修正後の成功を確認できる。

ここで一旦エラー自体は解消。
ただし、実際のサイトを確認すると別の問題が見つかった。
ビルドは通ったがinitial-setupが別カテゴリになった#
最初のschemaエラーを直すとビルドは通ったが、公開画面を確認すると分類が意図どおりではなかった。
フォルダ名・内部値・表示名は別物だった#
記事の配置先は、
src/content/blog/web-development/initial-setup/
なので、最初はsubcategoryもinitial-setupでよいと考えた。
しかし、ゆまラボで既に「初期構築」に使っている内部値はsetup。
つまり、
フォルダ名 initial-setup
subcategory setup
表示名 初期構築
という別々の役割になる。
フォルダ名に合わせてsubcategory: "initial-setup"とすると、taxonomy側では未定義の値として扱われ、「その他のサブカテゴリ」に入ってしまう。
そこで最終的にFrontmatterを次の形へ変更した。
category: "web-development"
subcategory: "setup"
重要なのは、記事の分類はFrontmatterを基準にし、フォルダ名とsubcategoryを無理に一致させないこと。
修正後は「その他のサブカテゴリ」が消え、「初期構築」が3件から4件になった。

第11回で見つかった英語表示も同じ考え方で整理する#
第11回では、development-supportがサブカテゴリの表示へそのまま出る問題を確認した。内部値と画面表示名をtaxonomy側で分ける考え方は、今回のcategory・subcategoryでも同じになる。詳細はサイトの共通UIを整える―ロゴ・スマホナビ・RSS導線を改善に残している。
タグ重複も見つかったが、仕組みからの対策は第16回へ分ける#
カテゴリを確認したあと、タグ一覧も見てみる。
すると別の問題が見つかった。
#Astroが1件と10件に分かれ、#静的サイトも同じ名前が別々に表示されていた。

見た目が同じでも、Frontmatter側の大文字小文字、前後空白、Unicode、slug生成などに差があると、内部的には別タグとして扱われる可能性がある。
タグ処理も見直し、集計・slug生成・表示で同じ正規化ルールを使うように修正する。
考え方はカテゴリと同じで、内部で扱う値と画面に表示する名前を分ける。
例えばAstroなら、
内部キー astro
表示名 Astro
という形。
Markdown側に表記揺れがある場合も同じ表記へ寄せ、タグ一覧とタグ詳細ページで別々のルールを使わないようにする。
修正後のタグ一覧では、分裂していたタグが1つにまとまった。

#Astroは11件。
#静的サイトは2件。
以前のように同じ表示名が2つ並ばず、記事数も合算されている。
タグは記事が増えるほど表記揺れが起こりやすいので、記事ごとに気を付けるだけでなく、サイト側でも正規化しておく方が扱いやすい。
タグの正規化やaliasの詳細はAstroでタグの重複・表記揺れを防ぐ方法|タグマスタ・alias・正規化で管理へ分け、ここでは当時見つかった重複と統合結果だけを残す。
ビルド成功後も公開画面まで確認する#
カテゴリとタグの修正をまとめて再度pushする。当時はトップページの縦方向の余白も同時に小さく修正した。
最終ビルドも正常に完了した。

ビルド履歴を見ると、最初に失敗したビルド、その後のFrontmatter修正、今回のタグとトップページ修正まで流れを追える。

今回もローカルだけで終わらせず、実際にCloudflare Workersへデプロイされた状態まで確認して完了。
Content Collectionsを使って分かったこと#
最初の原因は単純で、Content Collectionのschemaに日本語のcategoryとsubcategoryを渡していたこと。
ただ、そこだけ直せば終わりではなかった。
ビルドが通ったあとにサイトを見ることで、
initial-setupが既存のsetupと別扱いになる- 同じタグが複数に分裂する
- トップページの縦余白も同時に確認した
という別の問題も見つかった。
ビルド成功は大事だが、ビルドが通ることと、サイト上で意図した状態になることは別。
今回のように、
エラーを確認
↓
原因を修正
↓
ビルド成功
↓
公開画面を確認
↓
表示上の問題を追加で修正
↓
もう一度ビルドと公開を確認
という流れで見ていくと、単にエラーを消すだけでなく、公開後の状態まで確認できる。
AstroのContent CollectionsはFrontmatterをschemaでチェックできるので、間違った値をビルド時に止められるのは便利。
一方で、setupとinitial-setupのようにschema上は正しくてもサイト内のtaxonomyとしては別物というケースまでは自動では判断できない。
カテゴリ、サブカテゴリ、タグの内部値を増やすときは、既存の定義を確認してから追加する必要がある。
今回はCloudflareのビルドエラーから始まり、記事分類、タグ、トップページまで続けて修正する回になった。


