自動投稿ツールが、成功した予約投稿を「失敗」と誤判定していた話
会社員が自宅のWindows PCで、月額ほぼ0円の構成で副業のパイプラインを4本、夜間も無人で動かしている。このnoteの記事自体も、そのうちの一つの仕組みが毎朝自動で書いている。今日はその仕組みの中で「書いた記事を実際にnoteへ送る」処理を担うスクリプトが、2026年9月3日に実際に踏んだ、成功しているのに失敗と報告してしまうバグの話を書く。
結論
2026年9月3日、noteの予約投稿機能を使って記事を予約したところ、画面には「予約投稿が完了しました」まで表示され、予約自体は成立していた。ところが、その結果を判定していたコードは別の見方をしていて、成功しているのに「失敗」と報告していた。原因は、完了を知らせるダイアログが元の画面の上に重なるだけで、裏にあった予約投稿ボタンの要素自体は消えずに残っていたことだった。
状況
このnoteの記事を書く仕組みは、動いている各パイプラインが毎日吐くログと実測値を集めて記事を書き、公開前の検査を通し、最後にnoteのエディタへ実際に打ち込む、という流れで動いている。noteには外部から使える公開APIが無いため、最後の「noteに送る」処理は、ログイン済みの状態を保存しておいたブラウザを自動操作して、実際の画面のボタンをクリックする形で実装している。この処理を担うスクリプトは、下書きの作成、見出し画像の添付、ハッシュタグの入力、予約投稿の設定までをまとめて受け持っている。なお、実際に「公開する」を確定させるボタンだけは人がその場で押す設計にしていて、機械的な全自動公開はしていない。
数字
項目 値
予約投稿の送信を含むスクリプトの行数(post_note.py, 2026-09-03時点) 713行
見出し画像を生成する側のスクリプトの行数(make_header.py) 134行
```何が起きたか
スクリプトのコメントには、この件について実際にこう書き残してある。
# 成否は **「予約投稿が完了しました」の有無**で判定する。
# 「予約投稿ボタンがまだ見えるか」で判定すると必ず誤判定する——
# 完了ダイアログは元の画面の**上に**重なるだけで、裏のボタンは
# 消えないため。実際それで成功を失敗と報告した(2026-09-03)。
```予約は正しく設定され、noteの画面上でも完了扱いになっていた。それでもスクリプトは「失敗しました」というメッセージを返してきた。
なぜそうなったか
最初の判定ロジックは「予約投稿ボタンが画面から消えたら成功」という考え方だった。ところがnoteの完了ダイアログは、下にある元の画面を消さずに、その上に重ねて表示するだけの作りになっている。そのため予約が成功していても、裏側にある「予約投稿」ボタンの要素はDOM上にそのまま残り続ける。「そのボタンがまだ見えるかどうか」だけを見ている限り、成功していても常に「まだ見えている」、つまり「失敗」という判定になってしまう。ボタンの見た目の状態と、処理が実際に完了したかどうかは、別のことを見ている。
どう直したか
判定の基準を「ボタンが消えたか」から「完了を知らせる文言が画面に出たか」に変えた。
python
done = page.locator('text="予約投稿が完了しました"')
if done.count() == 0:
shot = _shot(page, "schedule_submit_failed")
browser.close()
raise SystemExit(
"「予約投稿」を押しましたが完了の表示が出ません。"
f"下書きは残っています: {shot}")
```ボタンの状態を推測するのではなく、成功したときにしか出ない文言そのものを探す形にしたことで、完了ダイアログが裏の画面を隠さない作りでも正しく判定できるようになった。判定に失敗した場合でも下書き自体は残る設計にしてあるので、誤判定で記事が消えることはない。
まだ残っている問題
この修正は「予約投稿が完了しました」という特定の文言に依存している。noteが表示文言を変えれば、また同じ形で誤判定が起きる。同じスクリプトの中には、見出し画像を追加するボタンのようにテキストも属性も無く座標だけで掴んでいる箇所や、トリミング確定のボタンのようにモーダルの内側かどうかで挙動が変わる箇所もあり、いずれもnote側の画面変更に弱い作りのままになっている。今回直したのは予約投稿の判定1箇所だけで、他の箇所を横断して同じ観点で洗い直す作業はまだ手を付けていない。
※この記事は Claude Code を使って構成・執筆しています。数値はすべて自分の環境で実際に計測したものです。
