se-hari.com se-hari.com

invalid_cursor — Cursor paginasi tidak bisa dibaca

HTTP 400. Nilai `starting_after` yang Anda kirim bukan cursor yang pernah kami keluarkan. Cursor bersifat buram: ia menyandikan posisi baris terakhir dan…

2 menit baca Diperbarui 15 Agustus 2026 Lihat sebagai Markdown

invalid_cursor adalah kode error HTTP 400 pada Se-Hari API. Nilai starting_after yang Anda kirim bukan cursor yang pernah kami keluarkan. Cursor bersifat buram: ia menyandikan posisi baris terakhir dan tidak dimaksudkan untuk dibaca, dibuat, atau dimodifikasi klien.

#Bentuk responsnya

Semua error Se-Hari memakai amplop yang sama. Yang perlu dicabang di kode Anda adalah code, bukan message — teks pesan bisa kami perbaiki sewaktu-waktu, sedangkan code adalah kontrak publik yang hanya berubah lewat versi API baru.

json
{
  "error": {
    "code": "invalid_cursor",
    "message": "Contoh pesan untuk invalid_cursor.",
    "docs_url": "https://se-hari.com/docs/error/invalid-cursor",
    "request_id": "req_a1b2c3d4e5f6",
    "details": {}
  }
}

#Kapan ini muncul

Kode ini hanya muncul pada endpoint daftar, dan hampir selalu berarti kode paginasi ditulis dengan asumsi offset. Gejala yang menyertainya sering lebih membingungkan daripada errornya sendiri: sebagian penelusuran berhasil, lalu berhenti di tengah dengan 400 — karena halaman pertama tidak butuh cursor sama sekali, sehingga bug-nya baru terlihat pada halaman kedua.

#Kenapa ini terjadi

  • Cursor dibuat sendiri, misalnya diisi id baris terakhir
  • Cursor terpotong saat disimpan ke kolom database yang terlalu pendek
  • Cursor di-URL-encode dua kali oleh HTTP client
  • Cursor dari endpoint lain dipakai di endpoint ini — setiap daftar punya ruang cursor sendiri

#Cara memperbaikinya

Kirim kembali persis nilai next_cursor dari respons sebelumnya, tanpa perubahan apa pun. Kalau Anda menyimpannya, pastikan kolomnya cukup panjang; cursor bisa melebihi 60 karakter.

#Yang memicu error

bash
# SALAH: memakai id baris terakhir sebagai cursor
curl "https://se-hari.com/api/v1/notes?starting_after=c0ffee00-1111-2222-3333-444455556666" \
  -H "Authorization: Bearer $SEHARI_API_KEY"

#Yang seharusnya

bash
# BENAR: memakai next_cursor apa adanya
CURSOR=$(curl -s "https://se-hari.com/api/v1/notes?limit=100" \
  -H "Authorization: Bearer $SEHARI_API_KEY" | jq -r '.next_cursor')

curl "https://se-hari.com/api/v1/notes?limit=100&starting_after=$CURSOR" \
  -H "Authorization: Bearer $SEHARI_API_KEY"

#Aman diulang?

Percuma tanpa perubahan. Ambil ulang halaman pertama untuk mendapatkan cursor yang sah, lalu lanjutkan dari sana. Mengulang dengan cursor yang sama hanya menghasilkan error yang sama.

#Jangan tertukar dengan

Ini bukan not_found. Cursor yang menunjuk baris yang sudah terhapus tetap valid dan tetap dijawab dengan halaman berikutnya; yang ditolak di sini adalah cursor yang bentuknya tidak kami kenali sama sekali. Kalau daftar Anda kembali kosong tanpa error, itu bukan kode ini melainkan tanda bahwa filternya memang tidak cocok dengan apa pun.

#Mencegahnya terulang

Perlakukan cursor sebagai token buram. Jangan menyimpannya di kolom varchar(32), jangan memotongnya untuk log, dan jangan pernah membangunnya sendiri. Kalau Anda perlu melanjutkan penelusuran di proses lain, simpan seluruh nilainya apa adanya. Untuk pekerjaan besar, pola paling aman adalah menyelesaikan satu penelusuran penuh dalam satu proses, karena cursor menggambarkan posisi dalam daftar yang isinya bisa bertambah di antara dua sesi.

#Menangani ini di kode

Cabangkan pada error.code, dan bedakan kegagalan yang layak diulang dari yang tidak. Mengulang kegagalan yang tidak akan pernah berhasil hanya menghabiskan kuota rate limit — dan menyembunyikan kegagalan yang sebenarnya butuh perhatian Anda.

javascript
const res = await fetch('https://se-hari.com/api/v1/me', {
	headers: { Authorization: `Bearer ${process.env.SEHARI_API_KEY}` }
});

if (!res.ok) {
	const { error } = await res.json();

	if (error.code === 'invalid_cursor') {
		// Kirim kembali persis nilai `next_cursor` dari respons sebelumnya, tanpa perubahan apa…
		console.error(error.message, error.details);
	}

	// request_id adalah satu-satunya cara kami menemukan request ini di log.
	console.error(`request_id: ${error.request_id}`);
}

#Selanjutnya

Pertanyaan umum

Apa arti error invalid_cursor di Se-Hari API?

HTTP 400. Nilai `starting_after` yang Anda kirim bukan cursor yang pernah kami keluarkan. Cursor bersifat buram: ia menyandikan posisi baris terakhir dan tidak dimaksudkan untuk dibaca, dibuat, atau dimodifikasi klien.

Apakah aman mengulang request yang gagal dengan invalid_cursor?

Percuma tanpa perubahan. Ambil ulang halaman pertama untuk mendapatkan cursor yang sah, lalu lanjutkan dari sana. Mengulang dengan cursor yang sama hanya menghasilkan error yang sama.

Bagaimana cara memperbaiki invalid_cursor?

Kirim kembali persis nilai `next_cursor` dari respons sebelumnya, tanpa perubahan apa pun. Kalau Anda menyimpannya, pastikan kolomnya cukup panjang; cursor bisa melebihi 60 karakter.

Siap mencoba?

Buat API key gratis di dashboard — tidak ada biaya berlangganan, kredit terpakai hanya saat Anda benar-benar memproses rekaman atau membuat meeting.

Buat API Key