# 1 つの記事を商品ごとに分ける処理で起きた 3 つの取り違え：子が親になり、共有リンクが別の店を指し、名前が 2 つの商品のものだった

> 分けた「子」の記事に親向けの処理をもう一度かけて、締切当日の抽選 60 件（23 店）が消えた。13 店が共有するリンクで別の店の親を引いた。2 つの商品が名乗る名前が 267 組あった。画面に何も出ないまま、本物が消える失敗の記録。

- URL: https://koshinstudio.com/notes/split-mixups/
- 公開: 2026-10-17
- 書いた人: Koshin（https://koshinstudio.com/about/）
- サイト: Koshin Studio

  English version (https://koshinstudio.com/en/notes/split-mixups/)

トレカダッシュ 開発の記録 ／ 2026年9月

  iOS アプリ「トレカダッシュ (https://koshinstudio.com/works/torecadash/)」には、お店の告知を、商品ごとの記事に分ける処理があります。1 つの告知に「ポケモンカードの A と B の抽選」と書いてあれば、A の記事と B の記事に分けます。分けた記事を「子」、元の記事を「親」と呼びます。

  この処理のまわりで、3 つの「取り違え」が見つかりました。どれも、画面には何も出ないまま、本物の抽選が消える失敗です。

  数字は、2026 年 9 月の作業の記録（9 月 5 日と 9 月 20 日の分を含む）から書いています。

## 1. 子に、親向けの処理をもう一度かけた（9 月 20 日）

  多角的に点検していて、その日の 23:59 が締切の抽選、60 件（23 店）が、全部フィードから消えているのが見つかりました。

  子の記事は、親のチラシの画像と、親の題名（splitFromTitle）を、そのまま持っています。複数の商品が書かれた記事を聞き直す処理が、この子を見て、「9 商品が載っている」と読みました。子の商品の欄は空になり、「9 件」と書き換えられました。そして翌日、総称の記事（特定の商品を指さない記事）を整理する処理が、「商品が無い総称だ」として、伏せました。

  割った先の商品の ID は、すでにいる兄弟と同じなので、新しい記事は 0 件でした。その商品だけが、消えたのです。

  同じ根っこの問題は、もう 1 つありました。結果発表や当選者向けの案内を見分ける判定が、子の題名は商品名だけで、本文（親の題名）が届かないので、すり抜けていました（16 件）。

  直し方は、記事を集めて判定したり伏せたりする処理を足すときに、子を除く（splitFromArticleId を持つ記事を除く）か、親の題名を本文として渡すか、どちらかを必ず決めることでした。「子だから触らない」の目印には、URL の中の印ではなく、記事の項目を使います。URL の印は、応募先の張り替えで消えるからです。

## 2. リンクだけで親を探したら、別の店の記事が出てきた

  ふるいちという店の、2 商品をまとめた告知が、10 件、分割されませんでした。親の記事を探す関数が、リンクだけで探していたからです。

  この店のチェーンは、同じ共有のページを、13 店が同じリンクで持っています。リンクだけで探すと、次のどれかに当たりました。

- リンクだけで決まる、決め打ちの ID。

- 同じリンクを持つ記事を探して、先頭の 1 件を取る。

- 応募先の張り替えで印が消えた子の記事（親と同じリンクになる）。

  その結果、チェーン全体の別の店の記事や、子の記事を親として、何度も分割していました。ログに「2 商品へ分割しました」が、毎回同じ親で出ていました。

  リンクは、店を特定する鍵ではありません。共有のページ、引用、まとめ記事の由来で、同じリンクを複数の記事が持ちます。直し方は、記事をリンクで引くときに、サイトと店名も条件に入れること、子の記事を親にしないことでした。「ログに同じ親の ID が何度も出たら疑う」も、教訓として残しました。

## 3. 2 つの商品が名乗る名前は、どちらも特定しない（9 月 5 日）

  商品には、別の呼び方（別表記）を登録しておきます。「30th CELEBRATION BOX」という呼び方が、拡張パック「30th CELEBRATION」と、別の商品「30th CELEBRATION FUTURISTIC BOX」の両方の別表記に入っていました。

  この名前は、どちらの商品も特定しません。AI に候補として見せると、そのとき、どちらを選んだかで結果が決まります。実際に、表示中の 25 件が、別の商品の名前で出ていました。

  数えると、こういう「2 つ以上の商品が名乗る名前」は、267 組、321 件ありました。

  同じ形の別の失敗もありました。店名を「＠ より前」で切る処理が、「カードショップ＠ほ～む。」の 3 支店を1 つの店に潰し、毎日、2 支店を「重複」として畳んでいました。

  直し方は、名前で何かを特定する仕組みを作ったら、「その名前を名乗るものが 2 つ以上ないか」を数えることでした。監査を 1 本作って、0 件を保ちます。残す相手は、機械的に決まるときだけです。その名前を正式名にしている商品がちょうど 1 つなら、そこだけに残す。決まらないなら、全部から外す。足す側（入口）と、掃除する側の両方に、同じ判定を置きます。片方だけだと、外したそばから足し直されます。

## 分かったこと

> 分けた先の記事は、元の記事ではない。名前は、持ち主が 1 つのときだけ、鍵になる。

- 派生したものに、元のものの処理を、もう一度かけない。子の目印を、記事の項目に持たせる。

- リンクは、鍵ではない。サイトと店名も条件にする。

- 名前の持ち主を数える。2 つ以上が名乗る名前は、何も特定しません。

- 伏せる処理を足したら、代わりが本当に表示中かを数える。伏せた側だけを見ても、消しすぎは見えません。

  この話に出てくるもの

- トレカダッシュ (https://koshinstudio.com/works/torecadash/) — トレカの抽選・予約・先着の情報を集める iPhone アプリ

- 「9種セット」を中身ごとに分けて、偽の商品が80個できていた (https://koshinstudio.com/notes/fake-products/) — 同じ分割の処理の、別の失敗

- 本物の抽選を、静かに捨てていた 4 つの実例 (https://koshinstudio.com/notes/silent-discard/) — 画面に出ない失敗の、別の実例

- 一度だけ生まれた誤字が、店ごとに増えていった (https://koshinstudio.com/notes/typo-catalog/) — 商品名の取り違えの、別の経路
