# instinct: backfill/ETLボットがDB欠損を埋めない時はまず接続文字列のハードコードを疑う
backfill/ETL/補完系ボットが「動いているはずなのにDB欠損が何ヶ月も埋まらない」時、
バグや収集元サイト変更より先に**ボットのDB接続文字列のハードコード**を疑う。
anime#372 で判明: backfillボット8本が存在しない旧DB
`postgresql://shadow:shadow_dev_pass_2026@127.0.0.1:5432/shadow` をハードコードし、
`role "shadow" does not exist` で全件空振りしていた。本番アプリは
`postgresql+asyncpg://ubuntu@/vvv_prod?host=/var/run/postgresql`(peer認証)で正常稼働
していたのに、ボットだけが死んだ接続を見ていた。これがデータ欠損(放送開始日58%等)
放置の真因だった。エラーログにも出ず「静かに失敗」していた点が厄介。
**Why:** DBが分裂/移設/ホスト退役(cure/arcana廃止)した履歴があると、旧接続を
ハードコードしたスクリプトが残骸として生き残る。正規パターン(`os.environ["DATABASE_URL"]`
+ `normalize_dsn`)を使うボットは追従するが、ハードコード組は取り残される。
**How to apply:**
1. backfillが効かない時は最初に `grep -rl 'ハードコードされたDSN\|shadow_dev_pass' bots/` で死接続を洗う
2. `load_dotenv()` 引数なしも危険(cwd依存・失敗時サイレントにデフォルト値へフォールバック)
→ 絶対パス `load_dotenv(ROOT/".env", override=False)` に統一
3. 動いている同種ボット(anime なら `anilist_bot.py`)の接続パターンに揃える(発明しない)
4. 修正後は必ず dry-run→少量本番書込で「欠損率が実際に下がる」ことをSQLで数値確認
関連: [[instinct_vvv_prod_direct_edit_git_drift]](本番フォルダのdrift) /
[[project_shadow_arcana_topology]](cure/arcana退役の経緯)
---
(migrated from local memory/instinct_dead_db_connection_silent_data_drought.md)
instinct: backfill/ETLボットがDB欠損を埋めない時はまず接続文字列のハードコードを疑う