【ITニュース解説】A mistake changed my career — production went down at 2am.
2026年09月28日に「Dev.to」が公開したITニュース「A mistake changed my career — production went down at 2am.」について初心者にもわかりやすく解説しています。
ITニュース概要
深夜、システム障害で顧客が利用不可に。ログは全て成功を示すが、実際は処理が完了していなかった。原因は成功ログを先に記録したため。システム自身が報告する成功は信用できず、コードを書いた主体とは別の視点で、本当に成功したか厳しく検証することが重要だと学んだ。
ITニュース解説
あるエンジニアは、深夜2時に顧客からの電話で起こされた。顧客は自分のアカウントにログインできないという。すぐにシステムのログを確認したが、そこにはエラーを示す赤い線は一つもなく、すべてのログが「リクエストを受信した」「処理は成功した」「書き込みが承認された」と、完璧な成功を報告していた。システムは完璧に動作していると主張しているにもかかわらず、目の前の顧客はアカウントから締め出されているという、矛盾した状況に直面したのだ。
これは、システムが何らかの問題を抱えていれば必ずログに記録されるはずだ、というエンジニアが抱く一般的な前提を覆す出来事だった。通常、異常があればエラーメッセージやスタックトレースといった原因を追跡する情報が記録される。しかし、この時のシステムは、バグによって嘘をついていたわけではなかった。むしろ、エンジニアが書いたコードが、まだ成功が確実ではない瞬間に「成功」と記録するように指示されていたため、システムは指示通りにその「嘘」を記録していたのである。コードがシステム外部の世界の状態について間違っていたのではなく、システム自身が自分自身の状態について間違った情報を記録していたのだ。
このバグの原因は、後から判明すると驚くほど単純なものだった。エンジニアは、顧客からのリクエストを「承認(acknowledgement)」してから、実際にデータを「永続化(persist)」する、という処理順序でコードを書いていた。開発環境でのデモやテスト、エンジニアの手元のマシンでは、この承認と永続化の二つのステップは非常に短時間で連続して実行され、その間のギャップはほとんど存在しなかった。そのため、コードは注意深く書かれたように見え、コードレビューも通り、問題ないと判断されていた。
しかしある夜、システムにリトライ処理が走った際に、この「承認」と「永続化」の間のミリ秒単位のわずかな隙間を突かれたのである。システムは顧客に承認応答を返したが、その直後にデータの永続化処理が何らかの理由で完了しなかった。システムから見れば、すでに「良い知らせ」を顧客に伝えたため、自身は成功したと判断し、成功ログを記録して次の処理へ移行した。一方、顧客の視点では、データは保存されず、まるで存在が消去されたかのようにアカウントから締め出されてしまったのだ。何もエラーを吐くことなく、何も異常を示すことなく、システムは自信満々に「成功」を報告し続けていた。これは、まだ何が起こっているか分からない間に、システム自身が成功を祝ってしまった状態だった。
この経験から得られた最大の教訓は、単に「もっとテストを増やすべきだった」という単純なものではなかった。確かに、このバグを再現するようなリトライテストはその後追加されたが、それは本質的な解決策ではなかったという。このコードはすでに十分にテストされており、デモも完璧だったのだ。問題の本質は、自身の作業をチェックするために使用していたあらゆる検証手段が、そのコードを書いた本人、つまり「作者」の視点から報告されていたことにあった。そして、その作者にはまさに失敗が潜んでいた場所に「盲点」があったのだ。同じ盲点を持つ同じ思考でいくらテストを追加しても、それらはすべて同じように「成功」を報告し、結果として同じ場所で間違った判断を下すことになっただろう。
本当の教訓はもっと構造的なものだった。それは「コードを書く者が、そのコードが正しく動作すると証明する者であってはならない」という原則である。コードの作者は自分の作品に誇りを持ち、それが成功したと信じがちだ。しかし、「自信」と「正確性」は異なる概念であり、作者は自信の側面しか制御できない。コードの正確性を保証するためには、作者の主張を疑い、積極的に失敗を再現しようとする、別の視点と役割が必要なのだ。障害が起きた夜、筆者はコードの作者であり、そのコードの検証者でもあった。同じ人物が両方の役割を担っていたため、システムの「成功」の主張を疑う者は誰もいなかったのである。
この問題は、エンジニアの経験が浅いことによるミスでもなければ、AIの特有の問題でもない。このコードは丁寧で、レビューも十分に受けたものだった。しかし、成功が重要となる唯一の瞬間に、その成功について誤った情報を記録してしまったのだ。これは、コードを書いた本人(作者)が、そのコードの動作を保証する者(証人)でもあったことによって生じる「座席の問題」である。現代においてAIがコードの大部分を生成するようになっているが、AIもまた、人間と同様に「自信満々で、もっともらしい成功を報告するが、それが真実であるとは限らない」という同じ病理を抱えている。AIは自分の成果を最も説得力のある形で語るため、その作業が正しいと保証する役割を担わせてはならないのである。
この経験を元に、筆者は現在、以下の原則に基づいて行動している。まず、成功を示すログは、失敗しうる処理の「後」に記録する。例えば、データの永続化が完了してから成功を承認する「永続化後承認」の順序を徹底する。ログの記録順序は真実の主張であるため、そのように扱うのだ。次に、自分自身やAIが提案する解決策を安易に受け入れず、積極的にそれを「壊そう」と試みる。リトライ処理でどうなるか、深夜2時にどうなるか、不正な入力があった場合にどうなるかなど、最悪のシナリオを想定してテストする。また、コードを書いた作者以外の誰かが、そのコードを疑う「懐疑者」の役割を担うべきだ。この懐疑者の役割がプロセスに存在しない場合、それは障害発生時の筆者と同じく、一つの視点、一つの盲点、そして「成功」を示すグリーンログしかない状況に陥る。さらに、コストを伴う教訓は本番環境でのみ得られるという考えから、小規模でも早期に本番環境に近い場所でコードをリリースし、意図的に痛みを伴う経験を得ることで、障害への反射的な対応能力を高める。これをカナリアリリースと呼ぶ。
これらの原則は、筆者が現在開発しているエージェントプラットフォームの構築方法にも深く根ざしている。この業界全体で、コードを生成する「作者」を崇拝する傾向があるが、自信に満ちた成功の出力は、それが真実であるかどうかに関わらず生成されてしまう。筆者が深夜2時に経験した「嘘をつくログ」は、筆者が最初に経験した嘘つきのエージェントであり、決して最後ではないだろう。だからこそ、コードを書く者(作者)が、そのコードを承認する者であってはならないのだ。コードを生成する「作者」とは別に、失敗を再現し、真に成功が証明されるまで承認を拒否する「懐疑者」の役割が必要となる。そして、システムの限界を理解し、真の責任を負う「人間」が、最終的なマージ判断を下す。作者、懐疑者、人間という明確な役割分離こそが、筆者のシステム設計の根幹であり、深夜の緑色のログが教えてくれた重要な教訓なのだ。コードが成功を記録していることは、それ自体が成功の証拠にはならない。コードを書かなかった誰かが、それを確認する必要がある。
この障害は、一晩の睡眠、顧客からの信頼、そしてつらい一ヶ月間という代償を払わせたが、それと引き換えに、他の何よりも価値のある反射的な行動を筆者にもたらした。それは、何かが「うまくいった」と報告してきたとき、誰がそう言っているのかを常に問うことだ。もしそれが、実際にその作業を行ったものと同じ存在であるならば、それは真の答えではなく、いつか深夜2時に電話がかかってくる予兆なのだと。