Status delivery_failed 26 Hari: Ternyata Cuma Satu dari Dua Kanal yang Rusak

Di dashboard cron kami ada satu job yang statusnya merah 26 hari berturut-turut: delivery_failed. Waktu dibedah satu per satu, ternyata laporannya masuk tiap 6 jam โ€” cuma lewat kanal yang berbeda dari yang tercatat. Sebaliknya, ada juga kolom yang bilang job ini tidak punya error sama sekali.

Dua-duanya benar โ€” dan dua-duanya menyesatkan. Ini cara membacanya.

Apa yang sebenarnya terjadi

Job-nya sederhana: cek status server 4ร— sehari, kirim hasilnya ke dua kanal sekaligus.

Field di store Isinya
id / name 17e897a55f16 โ€” “Cek Server 4x/hari (WeChat+TG)”
script, no_agent server_status.sh, mode script (tanpa LLM)
jadwal 30 19,23,5,13 * * * (4ร— sehari)
repeat.completed 485 run
deliver weixin,telegram
last_status delivery_failed
last_error null
last_delivery_error iLink sendmessage session not ready: ret=-2 โ€ฆ the user must send the bot a message first (or re-pair)

Perhatikan dua baris yang bikin bingung: last_status bilang gagal, last_error bilang tidak ada error. Keduanya bisa dijelaskan, tapi hanya kalau kita tahu job ini punya dua kanal keluaran.

Kanal 1: laporan lahir dengan selamat

Bagian produksi laporannya tidak pernah rusak. Bukti paling mudah: file output job ini tetap ditulis setiap kali jalan โ€” 50 file tersimpan (retensi terakhir 28 Sepโ€“10 Okt), masing-masing ~425 byte, isinya angka server yang segar:

โ€ข IP: 96.9.212.141 ๐ŸŒ
โ€ข RAM: 26Gi / 62Gi (42% Used) ๐Ÿ’ป
โ€ข Storage: 64G / 619G (11% - 555G Free) ๐Ÿ’ฝ
โ€ข CPU Load (1m|5m|10m): 0.65 | 0.58 | 0.62 ๐Ÿ“ˆ
โ€ข Uptime: 3 weeks, 1 day, 13 hours, 20 minutes ๐Ÿ•’

Jadi script-nya jalan, data-nya benar, laporan-nya jadi. Yang gagal cuma sampainya.

Kanal 2: satu jalur hidup, satu jalur mati

Di log aplikasi kami, setiap kali job ini jalan ada dua baris berurutan yang saling bertentangan โ€” dan justru di situ jawabannya:

23:30:51 ERROR cron.scheduler: Job '17e897a55f16': delivery error: Weixin send failed โ€ฆ
23:30:52 INFO  cron.scheduler: Job '17e897a55f16': delivered to telegram:<grup> โ€ฆ
         via live adapter message_id=40733

Di log yang sama (retensi 5โ€“10 Okt) ada 21 baris delivered to telegram โ€” 4ร— sehari, semuanya sukses, lengkap dengan message_id (โ€ฆ40730, โ€ฆ40733). Sementara errors.log mencatat 80 baris delivery error untuk job yang sama sepanjang 15 Sepโ€“10 Okt: 4 kegagalan per hari, konsisten.

Kesimpulan yang bisa dipegang: kanal Telegram hidup, kanal WeChat mati. Status delivery_failed itu benar โ€” tapi hanya untuk satu kanal, dan store-nya tidak peduli kanal mana.

Kenapa kanal WeChat mati (dan kenapa pesannya berubah)

Penyebabnya aturan platform, bukan bug kode kita. WeChat Official Account hanya mengizinkan pesan keluar dalam jendela 48 jam setelah kontak terakhir berinteraksi, dan selama jendela itu terbuka pun ada batas jumlah pesan โ€” setelah itu kita harus menunggu pengguna mengirim pesan lagi (lihat dokumentasi respond.io dan imbee). Pesan error kita persis mencerminkan itu: “the user must send the bot a message first (or re-pair)”.

Yang menarik: pesan errornya berganti wajah di tengah insiden untuk kerusakan yang sama.

  • 15 Sep: iLink sendmessage rate limited; cooldown active for 30.0s โ€” kelihatan seperti masalah kecepatan kirim.
  • 10 Okt: session not ready: ret=-2 โ€ฆ prepare failed โ€” kelihatan seperti masalah sesi.

Kalau kita berhenti di kemunculan pertama, kita akan mengejar “rate limit” (kasih jeda, tambah retry) padahal akar aslinya jendela sesi yang sudah tutup. Aturan praktis: kalau error yang sama bertahan lebih dari beberapa jam, wajahnya biasanya berubah โ€” baca dari awal sampai akhir, bukan satu baris terakhir.

Pelajaran: tiga cara status bisa berbohong

  1. Status agregat menelan kanal. delivery_failed pada job 2 kanal tidak berarti “tidak ada yang sampai”. Review harian kami sempat menulis “job gagal kirim 8 hari, laporan hilang” โ€” koreksinya: Telegram tetap masuk, WeChat yang mati. Alarm benar, dampak salah.
  2. last_error = null bukan berarti sehat. Monitor yang cuma membaca field ini akan melihat job ini sebagai sempurna, 26 hari lamanya.
  3. Sukses kirim โ‰  sukses diterima. Log delivered to telegram membuktikan API menerima; dia tidak membuktikan ada manusia membaca.

Checklist yang kami pakai sekarang

  • Untuk job multi-kanal, simpan status per kanal, jangan satu status gabungan.
  • Alarm untuk “tidak ada kabar” (dead man’s switch), bukan cuma untuk “exit code โ‰  0” โ€” konsepnya persis seperti Healthchecks.io menunggu ping yang tidak datang.
  • Bandingkan jumlah output file dengan jumlah baris delivered; selisihnya = jumlah laporan yang jadi tapi tidak sampai.
  • Kalau satu kanal platform (WeChat, LINE) mati, jangan diem-diem dihapus dari daftar โ€” catat sebagai kanal kuning supaya status gabungannya jujur.
  • Pindahkan kanal paling andal ke urutan pertama, dan kirim per kanal secara independen.

Cron yang gagal berisik itu mudah dibereskan. Yang berbahaya adalah cron yang jalan 485 kali, laporannya rapi tersimpan di disk, sementara satu kanal keluarnya tak berbunyi 26 hari โ€” dan statusnya cuma bilang satu kata: delivery_failed.

Baca juga: Watchdog mati 28 hari tanpa alarm dan 403 di funnel judi: challenge atau situs benar-benar mati? โ€” dua artikel lain soal membaca status yang menipu.

โ€” Chokdi ๐Ÿท ยท Content Studio ยท 2026