# 「動いてるのに間違ってる」— AI生成コードで一番多い、静かなバグ

> AIが書いたコードで最も多い不具合は脆弱性ではなく、エラーが出ないまま結果だけが間違っているバグです。集計が合わない、検索結果が欠ける、失敗が成功と表示される——その仕組みと、非エンジニアでも見つけられる確認方法を解説します。

- 公開日: 2026-08-06
- 著者: 友田 陽大
- タグ: バイブコーディング, AI駆動開発, 型安全, 個人開発, テスト
- URL: https://tomodahinata.com/blog/ai-generated-code-silent-bugs
- カテゴリ: AIで作ったアプリの運営
- 総合ガイド: https://tomodahinata.com/blog/ai-app-pre-launch-guide-for-non-engineers

## 要点

- AI生成コードで最も深刻かつ頻出なのはエラー処理と業務ロジックの誤り。脆弱性より多く、しかもエラーが出ないため何ヶ月も気づかれない
- 頻出パターンは5つ — 例外の握りつぶし、日付の境界、並び順が不定のページ送り、丸め誤差、部分的な失敗の無視。どれも画面上は正常に見える
- AIはハッピーパス（うまくいく道筋）を書くのが得意で、異常系は明示しない限り書かない。そして異常系こそが本番で起きる
- 対策は『壊れてはいけない条件』を先に日本語で書き出し、それをテストとしてAIに書かせること。コードが読めなくても条件は書ける
- 『AIが直したと言った』は確認にならない。修正後に同じ手順で再確認する習慣が、この領域では唯一の検証手段

---

セキュリティの話をしてきましたが、実は AI で作ったアプリで**いちばん多い不具合は脆弱性ではありません**。

**エラーが出ないまま、結果だけが間違っている。** これです。

そしてこの種のバグが厄介なのは、発見される機会がほとんど無いことです。画面は正常。エラーも出ない。ログにも残らない。数字が少し違うだけ。だから何ヶ月も、場合によっては永久に気づかれません。

---

## 1. なぜAIはこの種のバグを作るのか

AI は「うまくいく道筋」を書くのが非常に得意です。

「ユーザーの注文一覧を表示して」と頼めば、注文があるユーザーが、正常なデータで、1人だけアクセスしている状況で、完璧に動くコードを書きます。

書かないのは、こういう場合です。

- 注文が**1件も無い**とき
- 日付が**ちょうど境界**にあるとき（月末の23:59:59）
- **同時に2人**が同じデータを操作したとき
- 外部サービスが**遅い/落ちている**とき
- 数字が**マイナス**や極端に大きいとき
- 文字列に**絵文字や特殊文字**が入っているとき

これらは「異常系」と呼ばれます。そして——**本番で実際に起きるのは、まさにこれらです**。

理由は単純で、指示に含まれていないからです。AI が不注意なのではなく、あなたが「注文が0件のときは『まだ注文がありません』と表示して」と言わなかった。言うわけがありません。そんなことを考えるのは、一度それで痛い目に遭った人だけです。

---

## 2. 頻出する5つのパターン

実際によく見る形を、具体的に挙げます。どれも画面上は正常に見えます。

### パターン1: 例外の握りつぶし

いちばん多く、いちばん危険です。

処理が失敗したときに、その失敗を捕まえておきながら**何もしない**。エラーは画面にも記録にも出ず、処理は何事もなかったように次へ進みます。

```
【起きること】
- 保存されていないのに「保存しました」と表示される
- メールが送られていないのに完了画面が出る
- 決済が失敗しているのに注文が確定する
```

AI がこれを書く理由は、**エラーで止まらないようにするため**です。「エラーが出ます」と伝えると、AI は「エラーが出ないように」してくれる。それが「エラーを無視する」形になることがあります。

**確認方法**: わざと失敗させてみてください。ネットワークを切る、必須項目を空にする、極端に長い文字を入れる。それでも「成功しました」と出たら、握りつぶしています。

### パターン2: 日付の境界

集計やフィルタで、境界の1日（あるいは1秒）がずれる。

```
【起きること】
- 月次集計に月末の1日が入らない／翌月の1日が混ざる
- 「今日の注文」に、深夜0時前後の注文が入らない
- タイムゾーンがずれて、日本時間の朝が前日扱いになる
```

日本時間とUTC（世界標準時）の9時間差は、AI が特に間違えやすい場所です。手元で試すと正しく見えるのに、深夜帯だけずれる——という形で出ます。

**確認方法**: 月末と月初にデータを1件ずつ作り、両方が正しい月に集計されるか見てください。深夜0時前後のデータも試すと、なお確実です。

### パターン3: 並び順が不定のページ送り

一覧を「20件ずつ」表示している場合、**並び順を明示していないと、2ページ目で一部が抜けたり重複したりします**。

データベースは、並び順を指定しなければ「どの順で返してもよい」と考えます。1ページ目と2ページ目で違う順序が返ることが、実際に起こり得ます。PostgreSQL の公式ドキュメントにも、`ORDER BY` を指定しない `LIMIT` は行の順序が予測不能である旨が明記されています。

```
【起きること】
- ページ送りすると、一部の項目が表示されない
- 同じ項目が2ページに出る
- データが少ないうちは正常で、増えると突然おかしくなる
```

これは**データが増えてから顕在化する**のが特に厄介です。

**確認方法**: 30件ほどデータを入れて、1ページ目と2ページ目を見比べてください。合計が30件になり、重複が無いことを確認します。

### パターン4: 丸め誤差

金額や割合の計算で、小数点以下の扱いがずれる。

```
【起きること】
- 明細の合計と、表示されている総額が1円違う
- 消費税の計算が、税込→税抜→税込 で元に戻らない
- 割引を適用すると、合計がマイナスになる
```

1円の違いでも、会計上は問題になります。金額は小数で扱わず整数（円単位）で持つのが定石ですが、AI は指示しなければ小数で書くことがあります。

**確認方法**: 端数が出る金額（1円、333円、消費税の対象など）で試し、**明細を自分で足した数字と画面の合計を突き合わせてください**。

### パターン5: 部分的な失敗の無視

複数の処理をまとめて行うときに、途中で失敗しても続行してしまう。

```
【起きること】
- 注文は作られたが、在庫が減っていない
- ユーザーは削除されたが、そのユーザーのデータが残っている
- 決済は完了したが、注文レコードが作られていない
```

「まとめて成功するか、まとめて失敗するか」を保証する仕組み（トランザクション）が必要ですが、これも明示しないと入りません。

**確認方法**: これは目視が難しい部類です。次章の指示文でAIに調べさせるのが現実的です。

---

## 3. 見つけ方 — コードが読めなくてもできること

原則は1つです。

> **正解を別の方法で計算して、突き合わせる**

画面に出ている数字が正しいかどうかは、画面を見ても分かりません。別ルートで検算する必要があります。

### 方法1: 少ないデータで手計算

**これが最も確実です。**

データを3〜5件だけ入れた状態で、画面の集計と手計算を突き合わせます。件数が少なければ、暗算でも検算できます。

多くの人は「本物っぽいデータをたくさん入れて」試そうとしますが、それだと検算できません。**わざと少なくする**のがコツです。

### 方法2: 境界を狙う

正常な真ん中の値ではなく、端を試します。

- データが **0件** のとき
- データが **1件だけ** のとき
- **月末・月初**、**深夜0時前後**
- 金額 **0円**、**マイナス**
- 名前が **1文字**、**絵文字だけ**、**非常に長い**

AI は真ん中の値では間違えません。端で間違えます。

### 方法3: わざと失敗させる

- 途中でブラウザを閉じる
- 通信を切って送信する
- 同じボタンを素早く2回押す
- 別のタブで同じ操作を同時にする

「同じボタンを2回押す」は特に有効で、二重登録や二重送信を一発で暴きます。

---

## 4. 対策 — 「壊れてはいけない条件」を先に書く

ここが本題です。

多くの人は、AI に「テストを書いて」と頼みます。それ自体は良いのですが、**AI は自分が書いた実装に合わせてテストを書きます**。実装が間違っていれば、テストも同じ間違いを前提にします。テストは通り、バグは残ります。

有効なのは、**順序を逆にすること**です。

### あなたが書くもの

コードは書けなくても、**「これは必ず成り立つ」という条件は日本語で書けます**。むしろ、それを書けるのはあなただけです。アプリが何をすべきかを知っているのはあなたなので。

例:

```
- 注文の合計金額は、必ず明細の金額の合計と一致する
- 同じ検索を2回実行したら、必ず同じ順序で同じ件数が返る
- ページ送りで全ページを回ると、重複も欠落もなく全件が出る
- 残高は絶対にマイナスにならない
- ユーザーを削除したら、そのユーザーのデータは1件も残らない
- 月次集計は、月初0時00分00秒から月末23時59分59秒までを含む（日本時間）
- 決済が失敗したら、注文は作られない
- 保存に失敗したら、必ず画面にエラーが表示される
```

これを**先に書いて**、AI に「これをテストにして、実装が満たしているか確認して」と頼みます。

満たしていなければ、実装のほうを直します。この順序だと、AI は自分の実装を正当化できません。

---

## 5. AIに貼る指示

### 現状を調べる

```text
このアプリのコード全体を読んで、次の観点で問題がある箇所を洗い出し、
表にして報告してください。修正はまだしないでください。

(1) 例外を捕まえて何もしていない箇所（握りつぶし）。ユーザーにも記録
    にも失敗が伝わらない箇所
(2) 日付・時刻の境界の扱いが怪しい箇所。特にタイムゾーンの変換と、
    月初/月末の含み方
(3) 一覧取得で並び順（ORDER BY）を指定していない箇所。特にページ送り
    があるもの
(4) 金額や割合の計算で、小数を使っている箇所。丸めの方向が明示されて
    いない箇所
(5) 複数の更新をまとめているのに、トランザクションになっていない箇所
(6) データが0件・1件のときの分岐が無い箇所

各項目について「どういう条件のときに、画面上どう間違って見えるか」を
日本語で説明してください。私はコードが読めません。
```

### 条件をテストにする

```text
以下は、このアプリで必ず成り立つべき条件です。これらをテストとして
書き、実装が実際に満たしているか確認してください。満たしていない
ものがあれば、テストではなく実装のほうを修正してください。

- （ここに、あなたが書き出した条件を並べる）

テストは境界値（0件、1件、月末、深夜0時、金額0円やマイナス）を必ず
含めてください。テストが失敗した場合は、失敗した条件と、実装の
どこが原因かを日本語で説明してください。
```

---

## 6. 「直しました」を信じない

最後に、この領域で最も重要な習慣を1つ。

AI は「修正しました」と報告します。多くの場合、実際に修正されています。しかし**確認せずに信じるのは、この種のバグでは特に危険**です。エラーが出ないバグなので、直っていなくても何も起きないからです。

修正後は、**見つけたときと同じ手順で確認してください**。

- 少ないデータで手計算と突き合わせる
- 境界（月末、0件、1件）で試す
- わざと失敗させる

1回2〜3分です。この習慣があるかどうかが、公開後に静かに壊れているアプリと、そうでないアプリの差になります。

---

## まとめ

- AI生成コードで最も多い不具合は脆弱性ではなく、エラーが出ないまま結果が間違っているバグ
- AIはハッピーパスを書くのが得意で、異常系は明示しない限り書かない。本番で起きるのは異常系のほう
- 頻出は5つ — 例外の握りつぶし、日付の境界、並び順が不定のページ送り、丸め誤差、部分的な失敗の無視
- 見つけ方は「別の方法で検算する」。データを少なくして手計算、境界を狙う、わざと失敗させる
- 対策は「壊れてはいけない条件」を先に日本語で書き、それをテストにしてもらうこと。コードが読めなくても条件は書ける
- 「AIが直したと言った」は確認にならない。同じ手順で再確認する

セキュリティの穴は「攻撃されなければ起きない」問題ですが、この種のバグは**放っておいても必ず起きます**。優先度としては、[公開前の4項目](/blog/ai-app-pre-launch-guide-for-non-engineers)を潰したあと、次にここへ来るのが現実的です。
