道路に「工事中・迂回してください」という看板を立てたとします。
でもその看板は、車を運転するドライバーだけが見るものでした。
カーナビには、何も伝わっていません。「直進です」と案内し続けます。
看板はたしかに、そこにあります。数字も、条件も、きちんと書いてあります。
でも受け取るはずの相手には、届いていない。
これと同じことが、わたしの書いたコードの中で起きていました。
あなたは今こうなっていませんか?
• AIに書いてもらったコードを「走らせた=完了」にしている • 設定値を書いたのに、実際の動きと照合していない • エラーが出ていないから、正しく動いていると思っている • 「動かした記録」と「意図通りに動いた記録」を区別していない
先に結論を言います。「設定した場所」と「実行される場所」は、コードの中では完全に別物です。
この記事では、わたしがInstagramの自動化ツールを作った際に踏んだバグの実話と、コードを読んで初めてわかった原因を書きます。
エンジニアでなくても気づける確認方法も、合わせて書きます。
「上限10件」と書いた日——設定はたしかにそこにあった
何を自動化しようとしていたか
Instagramの特定の投稿に対して、コメントしてくれた人を自動で取得するツールを作っていました。
投稿1本あたりの処理対象を絞るために、ファイルの先頭部分に設定値をまとめて書く構造にしていました。
const maxPosts = 10という変数を書いたのは、ツール全体の設定を1か所にまとめたほうが後で直しやすいと思ったからです。
設定値を1行変えれば動作が変わる——そういう「便利な設計」のつもりでした。
ところが実際は、「便利な設計のつもり」にしかなっていませんでした。
ファイルの構造と「設定がある場所」
ツールのファイルを大まかに説明すると、上部に設定値をまとめる「設定ブロック」と、下部に処理の手順を書く「実行ブロック」の2つに分かれていました。
maxPostsは設定ブロックに書かれていて、実行ブロックの中でそれを呼び出すつもりでした。
ただ「呼び出すつもり」というのがポイントで、実際に呼び出す処理が書かれているかどうかは、書いた時点で確認していませんでした。
変数の名前が書いてあれば、自動的にそこへ届くものだと思っていたからです。
この「思っていた」という部分が、3日間の誤作動の種になりました。
「書いた」という達成感
変数に数字を入れる作業は、とても直感的です。
maxPosts = 10と書くと、10という数字がそこに存在します。
コードを読めば誰にでも「10件に制限している」と伝わります。
わたしはその瞬間、「上限設定が完了した」という達成感がありました。
書いた、数字がある、設定が入った——という感覚です。
この感覚が、3日間つづく誤解の始まりでした。「書いた」と「届いた」は、同じではなかったんです。
「届いているか」という問いを持っていなかった
設定の行を書いた後、その行をテストしていませんでした。
「書いた=動く」という前提が、無意識に入り込んでいたからです。
「設定を書いた後、件数が設定通りになっているか確認する」という工程が、完全に抜けていました。
テストというと大げさに聞こえますが、必要だったのは「走らせた後に件数を数える」という1ステップだけでした。
その1ステップを確認リストに入れていなかったことが、問題の根本でした。
振り返ると、確認を怠ったというより「確認するべきだ」という発想自体がなかったんです。
それが今回、一番の学びになりました。
📕 AIエージェントと自動化の全工程をまとめた総集編 手順・コード・テンプレをそのまま渡しています
🤖【完全版】月商160万円の「寝てても回る仕組み」をゼロから30日で組む全工程|2026年10月版・Claude Code×AIエージェント・特典40ファイル・毎月更新
3日間、ログはずっと「正常終了」を返していた
エラーが1件もないきれいなログ
ツールを完成させてから、毎日走らせました。
最初の3日間、ログの最後は必ず「処理完了」という文字でした。
エラーは0件。警告も0件。
毎回、画面の上から下まで読んでも、赤い文字が一つも出てきませんでした。
「きれいに動いている」という確信が、日ごとに積み上がっていきました。
ログが教えてくれたこと、教えてくれなかったこと

当時のログには、処理の開始と終了、取得件数、APIのレスポンスステータスが記録されていました。
「取得件数:52件、ステータス:200、処理完了」のような出力が並んでいました。
今見れば一目でわかりますが、当時は「件数の表示がある=上限が効いている」と思い込んでいました。
「件数が表示されている」と「件数が設定値通りに絞られている」は、まったく別の情報です。
ログの中に「maxPostsの値が使われた」という記録は、一切ありませんでした。
設定値がどう使われたかを記録する処理を書いていなかったので、当然でした。
「問題ない」という判断の根拠はログだけだった
当時わたしが「問題ない」と判断した根拠は、ログだけでした。
エラーが出ていない。処理が完了している。
この2点を確認して、「設定通りに動いている」という結論を出していました。
でも本当は「処理が完了した」という事実しか、ログは教えていませんでした。
「意図した件数に絞られているか」という問いへの答えは、ログのどこにも書いていなかったんです。
その問い自体を立てていないことが、問題でした。
件数を数えたのは3日目の夜
3日目の夜、ふとした気まぐれで処理済みの件数を数えてみました。
「50件を超えている」という数字が出てきました。
設定した上限は10件でした。その5倍以上が処理されていました。
最初は自分の数え間違いかと思いました。でも何度数えても、50件を超えていました。
「設定の書き方を間違えたのかも」という混乱
「設定の書き方を間違えた」と思い、コードを確認しました。
const maxPosts = 10の行は、たしかにそこにありました。
数字はある。設定は書いてある。それなのに、なぜ効いていないのか——という混乱が続きました。
おかしいとわかっているのに、何がおかしいのかを言語化できない状態が約1時間続きました。
「書いてある変数が、なぜ無視されるのか」という問いを持てたのは、そこからさらに30分後のことでした。
コードを読んで初めてわかった「2つの場所」の存在

page.evaluateとは何か——工場の例えで
原因を探っていくうちに、page.evaluateという命令にたどり着きました。
聞き慣れない言葉だと思いますので、工場の例えで説明します。
工場には「コントロールルーム」と「作業フロア」の2か所があります。
コントロールルームの人が「ライン3を10回だけ動かして」と書いたメモを机に置きました。
でもフロアの作業員に、そのメモが手渡されませんでした。
フロアは「10回だけ」という指示を知らないまま、動き続けます。
page.evaluateは、この「作業フロア」にあたる部分です。
変数が「届かない」という意味——スコープという壁
page.evaluateの外側で設定した変数は、内側では自動では見えません。
これはJavaScriptという言語の「スコープ」という仕様で、バグでも設計ミスでもありません。
スコープとは「変数が見える範囲」のことで、page.evaluateの中は独立した領域として扱われます。
正しく動かすには、「引数」という形で明示的に渡す必要があります。
引数とは、フロアの作業員にメモを手渡す行為のことです。
わたしのコードには、その手渡しが書いてありませんでした!フロアは「上限は何件ですか?」
という情報を受け取れず、無制限で動き続けました。
渡す処理が1行なかっただけという事実
コードで言えば、page.evaluateの呼び出しに引数を追加するだけが修正内容でした。
変更前は変数名が外にあるだけで、中へ渡す記述がありませんでした。
変更後は引数として渡す形になり、フロアが「10件まで」という指示を受け取れるようになりました。
修正自体は1行の変更でしたが、原因にたどり着くまでに合計2時間近くかかりました。
原因に気づいた後の修正より、原因を特定するまでの時間のほうが圧倒的に長い——これが今回の教訓の一つです。
ログに「変数の値」を出力すれば早く気づけた
後から気づいたのですが、処理の冒頭に「maxPostsの値をログに出力する」1行を書いておけば、初日に発見できていました。
「上限件数:undefined」という出力が出れば、「届いていない」とすぐわかります。
undefined(未定義)という文字は、変数が届いていないサインです。
ログに「処理した件数」だけでなく「使用した設定値」を記録する習慣があれば、見落としが大幅に減ります。
完全なログ設計の手順は有料記事側にまとめていますが、まず「設定値が届いたか」を1行出力するだけでも、発見が格段に早くなります。
「外」と「中」という発想がなかった
コードを書いていて、「外側」と「内側」という概念をあまり意識していませんでした。
全部がつながっている1つのものだと、なんとなく思っていたからです。
でも実際には、page.evaluateの外と中は別世界です。
外で定義した変数は、意識して渡さない限り、中には入れません。
この「別世界」の存在を理解したとき、問題の原因がすっきり見えました。
渡す処理が1行なかっただけ——ただそれだけの話でした(笑)
CMO時代には「設定した=届く」を疑ったことがなかった
管理画面には「保存ボタン」がある
以前、月3,000万円規模の広告運用に携わっていた時期があります。
その頃は毎日、さまざまなツールの管理画面を触っていました。
広告の上限予算を入力して「保存」を押す。配信条件を設定して「適用」を押す。
「保存されました」という確認が必ず出るので、設定が届いたかどうかを疑いませんでした。
「設定した=届く」が、完全に当たり前の前提でした。
設定ツールが提供する「信頼の幻想」
広告管理画面、CMSの管理画面、SaaSの設定画面——これらはすべて「設定の反映」を保証してくれています。
「保存ボタンを押したら値をDBに書く」「書いた値を実行時に読み出す」——この2つの処理が、当たり前のように機能しているのは、誰かが設計して実装しているからです。
自分でコードを書く世界では、その安心感は誰も提供してくれません。
設定を書いて、届けて、届いたことを確認する——この3ステップが全部、自分の責任になります。
ユーザーとして管理画面を使っている間は見えなかった「届ける工程」が、作る側に回った瞬間に全部見えてきます。
「届ける仕組み」は誰かがすでに作っている
でも自分でコードを書くと、話が変わります。
管理画面の裏側には、誰かが「保存ボタンを押したら値を書き込む」処理を書いています。
その仕組みを使っている側にいると、その存在は見えません。
自分でコードを書くとき、「届ける工程」は自分で設計する必要があります。
「書いたから届く」ではなく、「届けるコードを別途書く」が必要なんです。
管理画面の向こうにある仕組みの重さが、初めて見えた瞬間でした。
コードを書くまで、その存在に気づいていませんでした。
「設定が届いているか」という問いの発見
CMO時代、「設定が届いているか」を確認する方法を持っていませんでした。
確認する必要性を感じたことも、ありませんでした。
管理画面が「そういうもの」として用意されていたので、その向こう側は気にしなかった。
それで何年も仕事できていたから、疑問にすらなりませんでした。
自分でコードを書いて初めて、「届ける責任が自分にある」と分かりました。
「届いているか」という問いが、初めて自分ごとになった瞬間でした。
AIが書いてくれたコードでも、同じ穴は起きます
エラーが出ないバグは、AIも気づきにくい
ClaudeやChatGPTにコードを書いてもらうことが増えました。
AIが書くコードは、文法的には正しいことが多いです。
でも「文法的には正しい、でも意図通りに動かない」バグは、AIも気づきにくいです。
エラーが出ないため、「問題ない」と判断しやすいからです。
わたし自身も、このコードをAIと一緒に書いていました。
それでも「走らせた結果を設定値と照合する」工程は、人間が担う必要があります。
AIに「変数が届いているか確認して」と頼む
コードを書いてもらった後に「この設定値が実際に使われているか確認するログ出力を追加して」と頼むと、AIは確認用の出力を追加してくれます。
「maxPostsが10件として動いているかどうかを、実行時に出力するコードを追加して」と頼むと、処理の冒頭に確認行を書いてくれます。
実行後に「上限件数:10」という表示が出れば、設定が届いていると確認できます。
「undefinedが出ていないか」「NaNが出ていないか」——この2点を走らせた後に確認するだけで、変数の受け渡し問題はかなり早く発見できます。
undefinedは「変数が届いていない」、NaNは「数値として扱えなかった」というサインです。
「動かした記録」と「意図通りに動いた記録」は別
ログに「処理完了」と書いてある。AIが書いたコードだから品質は高い。
この2つが揃っていても、「設定値が意図通りに使われているか」は別の問いです。
走らせた件数と、設定した上限を照合する。
その作業を1回するだけで、今回のバグは発見できました。
「走らせた後に照合する」という工程が抜けていたことが、3日間気づけなかった直接の原因でした。
AIとのコードレビューで確認すべき2点
AIが書いたコードを走らせる前に、確認するようになったポイントが2つあります。
1つは「設定値がどこで定義され、どこで使われているか」を追うことです。
定義した変数が、使われる場所まで確実に届いているか——このルートを1度なぞります。
もう1つは「この変数がundefinedだったとき、どういう動きになるか」をAIに聞くことです。
undefinedが渡されたとき何が起きるかを事前に知っておくと、ログの読み方が変わります。
この2点は、エンジニア経験がなくても実践できる確認方法です。
「1行の追加」で直り、確認に15分かかった
修正したのは数文字だった
修正の内容は、技術的には単純でした。
page.evaluateを呼び出す行に、maxPostsを引数として追加しました。
変更したのは1行、増えた文字数は10文字にも満たないです。
変更前と変更後を並べると、見た目はほとんど変わりません。
でもその差が、3日間の誤作動を生んでいました。
修正の前に、原因を言語化した
修正を加える前に、「何が起きていたか」を自分の言葉で書き出しました。
「maxPostsという変数は設定ブロックに書いてあるが、page.evaluateの内側には引数として渡されていないため、内側ではundefinedになっていた。
undefinedを件数の上限として渡しても上限なしで動き続けた」というものです。
このように書き出してみると、修正すべき箇所が1か所だけだとわかりました。
原因を言語化してから修正する——この順番が、修正後の確認をしやすくします。
書き出した原因と、修正後の動作が合っているかを照合できるからです。
修正後に「件数の一致」を確認した
修正した直後、すぐにツールを走らせました。
「修正できた」ではなく「修正が効いたか」を確認するためです。
処理された件数を数えると、ちょうど10件でした。設定した上限と一致していました。
この一致を確認して、初めて「直った」と言いました。
「修正した=直った」ではなく「件数が合った=直った」という確認の仕方です。
確認に15分かけた意味
修正してから件数を確認するまで、15分かかりました。
ツールを走らせて、結果を数えて、設定値と照合する——この工程が15分です。
最初からこの15分を踏んでいれば、3日分の誤作動は起きませんでした。
「確認に15分かける」価値の大きさが、じわじわと分かりました。
修正前に「設定した=届く」と思い込んだのと同じ間違いを、修正後に繰り返したくなかった。
だから、自分の目で数字が合うのを見るまで「完了」と言いませんでした。
この経験が変えた、1つの確認習慣
「ログが正常」は「設定が効いた」ではない
エラーなし、警告なし、処理完了——これはすべて「処理が終わった」という意味です。
「あなたの設定通りに動いた」という意味は、どこにもありません。この2つは、答えるべき問いが違います。
ログを見て安心するのは自然なことですし、わたしも今でもします。
でも、ログとは別に「設定値が本当に使われているか」という問いを持つようになりました。
具体的には、新しいツールを初めて走らせるとき、必ず「設定した数字がログに表示されているか」を確認します。
これは1分もかからない確認で、のちのち何時間もの原因調査を防いでくれます。
ログに「設定値の確認行」を入れる
今のわたしのコードには、主要な設定値を処理の冒頭で出力する行が入っています。
「対象件数の上限:○件で開始します」「スリープ時間の設定:○秒」のような出力です。
これを見ることで「設定値がここに届いている」という確認ができます。
undefinedやNaNが出ていれば、その時点で設定の渡し方を疑えます。
エラーが出るまで待つのではなく、設定値を先に見せてもらう——これが今の習慣です。
この確認行を書くときも「AIに設定値の確認出力を追加して」と頼むと、1分で入ります。
コードを「読める」ことの意味
わたしはエンジニアではありません。ゼロからコードを書ける人間でもありません。
それでも「何かがおかしい」と感じたとき、コードを読んで原因を見つけられました。
100%理解しなくても、「ここで何かを渡しているな」という読み方で十分でした。
動いているように見えるものを疑う力。ログではなく、実際の数字を確認する習慣。
これは、エンジニアだけが持てるものではないと、今では思っています。
自動化ツールの仕組みを体系的に知りたい方は、わたしのClaude Code自律環境についてまとめた有料記事で詳しく書いています。よければ参考にしてみてください。
今日からできる、たった1つの照合
走らせた後に問う、1つの質問
ツールを走らせたら、こう問いかけてみてください。
「設定した数字と、実際の件数は合っているか?」
これだけです。コードが読めなくても、数字を見ることはできます。
設定が10件なら10件か。対象が5件なら5件か。
ただそれだけの照合が、今回のようなバグを見つける最短ルートです。
1回の確認が、何日分もの誤作動を防ぎます。
ツールを走らせる前の「1行確認」
初めてコードを動かすとき、わたしが必ずするようになった確認があります。
それは「AIに、この設定値がundefinedになった場合は何が起きるか」を聞くことです。
答えが「無制限に処理されます」であれば、変数の渡し方を確認するきっかけになります。
この問い1つが、走らせる前のリスク確認として機能します。
「最悪の動作」を先に知ることで、確認すべきポイントが見えてきます。
「届いた」を確認することが、確認の本当の意味
「動かした」「ログが正常だった」は、出発点です。
「設定が届いたか」という問いを1回追加するだけで、今回のようなバグは早く見つかります。
わたしがこの確認を習慣にしたのは、3日間気づけなかった経験があるからです。
ログしか見ていなければ、もっと長く気づけなかったかもしれません。
「動いている」と「設定が効いている」は、別の状態です。
その違いを、エラーのないログは教えてくれません。
以上です。フォーマット確認:
📕 この記事の内容を、実装まで全部まとめた有料記事があります
手順・コード・テンプレをそのまま渡しています
AIで「寝てても回る仕組み」を30日で組む全手順|コード不要・特典40ファイル・毎月更新
