同日に6本公開したら、記事一覧がファイル名順に並んだ
本記事にはアフィリエイト広告(PR)が含まれます。
このサイトは2026年8月9日に公開し、初日にまず6本の記事を続けて公開しました(この日の公開は最終的に7本ですが、7本目はこの話の修正後です)。その直後、トップの記事一覧が、公開した順ではない並びで表示されていることに気づきました。壊れたのは表示順だけで、バグと呼ぶほどの実害はありません。ただ、原因を調べていったら「誰も決めていなかった仕様」に行き着いたので、その記録です。
何が起きたか
一覧の並びは「新しい記事が上」になる想定でした。ところが実際の並びは、公開順でも作成順でもない。よく見ると、ファイル名のアルファベット順でした。
このサイトは自作の静的サイトジェネレータで動いていて、一覧の並び順は記事の frontmatter にある publishedAt(公開日)の降順で決めています。その publishedAt が「2026-08-09」という日付のみの記録だったので、同日に公開した6本は全部が同じ値、つまり6本同着でした。
原因を調べる
ソートキーが同値のとき、並びが何順になるか。これを誰も決めていませんでした。
決めていない場合、並びが消えるわけではありません。ソートに入る前の順序が、そのまま残ります。今回の入力順はディレクトリの読み込み順、つまりファイル名のアルファベット順でした。並び順を決めていたのは、仕様ではなくファイル名だったわけです。
「同日に複数公開する」は初日にやったばかりの操作なので、設計時に想定から漏れていたこと自体は不思議ではありません。ただ、日付のみでソートする設計は、同日複数公開がいつか起きれば必ず同着を生みます。時限式で埋まっていた穴でした。
実際にやったこと
修正は2段構えで、Pull Request 1本にまとめました。
1つ目は、これから公開する記事のための修正です。publishedAt を日付のみに加えて時刻つき(タイムゾーンオフセット必須)でも書けるようスキーマを拡張し、公開処理が実行時刻を秒まで自動で記録するようにしました。画面の表示は従来どおり日付のみで、時刻は並び順の決定にだけ使います。
1つ細かい落とし穴があって、時刻つきの値は YAML で引用符をつけて書く必要があります。引用符なしだと frontmatter のパーサが Date 型に変換してしまい、UTC に丸められて日付が1日ずれ得るためです。ここはスキーマのコメントに残しました。
2つ目は、公開済み6本の復元です。このサイトは「公開用の Pull Request を人間がマージした瞬間が公開」という仕組みにしているので、公開時刻の一次記録は GitHub のマージ履歴に残っています。そこから各記事の実際のマージ時刻を引いて、6本の publishedAt に転記しました。JST で 13:38:27、14:49:15、14:49:32、14:49:59、14:50:17、14:50:31。フィールドに時刻を書いていなくても、事実は Git が覚えていました。
正直に書くと、日付を適当に1日ずつずらして並びを直す手もありました。ただ、それは公開日の偽装です。実データで復元できるなら、そうするべきでした。今回はできました。
修正の内訳はスキーマ拡張、公開処理の変更、表示の調整、公開済み6本への時刻転記。テストを7件足して計105件、表示上の変化は並び順だけです。
分かったこと
- 決めていない仕様は「無い」のではなく、暗黙の何かが埋めている。 今回はファイル名が、誰にも指示されないままソートの第二キーとして働いていました。決めるまで存在しないのではなく、決めるまで制御できないだけです
- 「何が正か」を決めた記録の設計が、後から自分を救う。 公開の事実を publish PR のマージに寄せてあったので、フィールドの記録が粗くても正しい順序を復元できました。復元元がなければ、偽装するか諦めるかの二択になっていたはずです
- 盛らない方針は、データ修正の場面でも効く。 「それらしい値で埋める」と「事実を転記する」の分かれ道は、記事の書き方だけでなくデータの直し方にも出てきます
同じことをする人へのポイント
- ソートキーを設計するときに「同着のとき何順になるか」を一度だけ問うてください。日付のみの記録で同日複数件は、いずれ必ず起きます
- 表示に使わない精度でも、並び順のためならデータは細かく持ってかまいません。表示の精度と記録の精度は、別々に決められます
- 公開・リリースの「事実」を Git のマージ履歴に寄せておくと、メタデータの記録漏れがあとから復元できます。逆に、手で書いたフィールドしか記録がないと、漏れた事実は消えます
今回の修正以降、公開処理は時刻を自動で書き込みます。実際、修正後の同日夜に公開した7本目の記事には、秒までの時刻が自動で記録されていました。この記事が公開されたとき、その publishedAt にも秒までの時刻が入っているはずです。
この記事は、運営者自身の実践記録に基づいています。