Skip to main content
Kesalahan muncul di dua tempat yang berbeda, dengan dua kosakata yang berbeda pula:
  • Kesalahan permintaan API — respons HTTP untuk panggilan API sinkron (otentikasi, penagihan, permintaan yang salah bentuk, resource yang tidak ditemukan). Lihat Kesalahan permintaan API.
  • Kode kegagalan prediction — permintaan sudah diterima dan masuk antrean, tetapi prediction itu sendiri berakhir dengan status: "failed". Kegagalannya dijelaskan oleh objek error pada prediction, yang Anda peroleh dari endpoint status prediction, dari pengiriman webhook, dan dari endpoint hasil. Lihat Kode kegagalan prediction.

Kode kegagalan prediction

Prediction yang gagal membawa objek error:
Prediction yang gagal tidak ditagih; kredit yang dicadangkan untuk permintaan tersebut akan dilepaskan kembali. Prediction yang tidak gagal membawa error: null. Lihat Catatan migrasi bila Anda mengintegrasikan sebelum 17 Agustus 2026.

Di mana kesalahan sampai ke Anda

Objek error yang sama diterbitkan di semua kanal, jadi Anda bisa membacanya di tempat yang memang sudah Anda pantau:

Membaca kegagalan dari endpoint hasil

Meminta output dari prediction yang gagal akan mengembalikan 400 berisi kegagalan yang menyebabkannya, di bawah kode tingkat permintaan PREDICTION_FAILED:
Dua kode di dua tingkat, dan keduanya bukan kosakata yang sama:
  • error.code bernilai PREDICTION_FAILED, sebuah kesalahan permintaan API yang berarti “prediction yang outputnya Anda minta tidak menghasilkan output”;
  • error.details adalah objek error milik prediction itu sendiri — identik dengan yang dilaporkan /status untuk permintaan yang sama, sehingga kedua endpoint tidak mungkin berbeda pendapat soal penyebab kegagalannya. Lakukan percabangan pada error.details.reason dan error.details.retryable.
error.message mengulang pesan milik prediction, jadi klien yang hanya membaca pesan di tingkat teratas pun tetap mendapat informasi yang berguna. Dua timestamp, dua makna. timestamp di tingkat teratas adalah saat respons HTTP ini dihasilkan; error.details.timestamp adalah saat prediction gagal. Untuk prediction yang Anda ambil beberapa hari kemudian, keduanya terpaut beberapa hari. Bacalah yang di dalam setiap kali yang Anda maksud adalah kegagalannya. Library klien resmi sudah membongkarnya untuk Anda: result() melempar kesalahan yang code, reason, dan retryable-nya adalah milik prediction itu sendiri, identik dengan yang dilempar subscribe() untuk kegagalan yang sama. Prediction yang masih mengantre atau sedang berjalan, maupun yang dibatalkan, tetap mengembalikan 400 umum yang sama seperti selama ini.

Menentukan perlu tidaknya mencoba ulang

Baca retryable. Field ini menjawab tepat satu pertanyaan — apakah mengirimkan permintaan yang identik ini sekali lagi akan memberi hasil yang berbeda? — dan ia tidak bergantung pada code: code yang sama bisa retryable pada satu kegagalan dan tidak pada kegagalan lain. retryable bersifat opsional. Ketika field ini tidak ada, gunakan default per-code pada tabel di bawah. Itulah perilaku Sunra sebelum field ini ada, jadi kembali ke default selalu aman; hanya saja kurang presisi.

code

reason

reason menyebutkan penyebab spesifik di balik code. Gunakan untuk metrik, routing, dan diagnosis dukungan teknis; untuk keputusan mencoba ulang, gunakan retryable. Setiap reason yang diterbitkan saat ini punya bagiannya sendiri di bawah ini, dan anchor-nya adalah reason itu sendiri — #input_fetch_failed, #moderation_blocked, dan seterusnya — sehingga sebuah laporan kesalahan bisa menautkan langsung ke artinya.

input_validation_failed

code: invalid_input · retryable: false Permintaan tidak lolos validasi schema atau parameter milik Sunra sendiri. message menyebutkan field yang bermasalah. Yang perlu dilakukan: perbaiki field yang disebutkan. Permintaan yang sama akan terus gagal.

provider_rejected_input

code: invalid_input · retryable: false Penyedia model menolak satu atau beberapa parameter input. Bila penyedia memberi tahu parameter mana, message menyampaikannya; sebagian penyedia hanya melaporkan bahwa inputnya tidak dapat diterima, dan dalam hal itu kami menyampaikannya apa adanya alih-alih menebak. Yang perlu dilakukan: periksa parameter Anda terhadap schema model — nilai di luar rentang, kombinasi yang tidak didukung, rasio aspek atau durasi yang tidak diterima model.

input_fetch_failed

code: invalid_input · retryable: false atau true File input yang dirujuk lewat URL tidak berhasil diambil. Inilah satu-satunya reason yang nilai retryable-nya benar-benar berubah-ubah, jadi bacalah field-nya, jangan diasumsikan:
  • false — host menolak kami: 4xx, alamat yang tidak boleh kami akses, redirect, atau file melebihi batas ukuran;
  • true — host sesaat tidak dapat dijangkau: 5xx, timeout, atau kegagalan DNS.
message menampilkan kembali URL yang Anda kirimkan sehingga Anda tahu input mana yang bermasalah — dengan query string dihapus, sehingga kredensial yang dibawa presigned URL tidak pernah dipantulkan kembali kepada Anda:
Yang perlu dilakukan: ketika retryable bernilai false, pastikan URL dapat diakses publik dan tautan presigned belum kedaluwarsa. Ketika bernilai true, coba lagi.

moderation_blocked

code: unsafe_content · retryable: false Diblokir oleh sistem keamanan konten penyedia model — baik prompt dan media yang masuk, maupun output yang dihasilkan. Yang perlu dilakukan: ubah prompt atau medianya. Mengirim ulang konten yang sama pasti diblokir lagi.

provider_rate_limited

code: service_provider_error · retryable: true Penyedia model sedang membatasi laju permintaan. Yang perlu dilakukan: coba lagi dengan backoff, atau arahkan ke model lain.

provider_unavailable

code: service_provider_error · retryable: true Penyedia model gagal melayani permintaan ini. Yang perlu dilakukan: coba lagi nanti, atau arahkan ke model lain.

provider_timeout

code: task_timeout · retryable: true Prediction tidak selesai dalam waktu yang diizinkan. Yang perlu dilakukan: coba lagi — saat beban sedang rendah, atau dengan permintaan yang lebih kecil (durasi lebih pendek, resolusi lebih rendah), peluangnya lebih besar.

provider_account_error

code: internal_server_error · retryable: false Akun kami sendiri pada penyedia model bermasalah — penagihan, kredensial, atau kuota permanen. Ini kesalahan di pihak kami, bukan pada input Anda. Yang perlu dilakukan: tidak ada yang perlu Anda lakukan; mencoba ulang tidak akan membantu, dan kami sudah menerima peringatan otomatis. Arahkan ke model lain bila kapasitas itu Anda butuhkan sekarang.

endpoint_misconfigured

code: internal_server_error · retryable: false Endpoint model ini salah dikonfigurasi di sisi kami. Yang perlu dilakukan: tidak ada yang perlu Anda lakukan; mencoba ulang tidak akan membantu, dan kami sudah menerima peringatan otomatis. Hubungi dukungan dengan menyertakan request_id bila mendesak.

queue_enqueue_failed

code: internal_server_error · retryable: true Prediction tidak berhasil dimasukkan ke antrean. Yang perlu dilakukan: kirim ulang permintaannya.

reaped_stalled

code: internal_server_error · retryable: true Prediction macet lalu dihentikan. Yang perlu dilakukan: kirim ulang permintaannya.

Nilai yang tidak dikenal

Baik code maupun reason adalah himpunan terbuka. Nilai baru ditambahkan seiring kami mengklasifikasikan lebih banyak kegagalan, tanpa pengumuman breaking change. Integrasi Anda tidak boleh crash, membuang error tersebut, atau menolak payload ketika menemui nilai yang tidak dikenalinya.
  • reason yang tidak dikenal — perlakukan seolah-olah reason tidak ada, lalu putuskan berdasarkan retryable (atau default per-code). Simpan nilai mentahnya di log Anda; itulah cara tercepat bagi dukungan teknis untuk mengidentifikasi kegagalan tersebut.
  • code yang tidak dikenal — perlakukan sebagai internal_server_error. Ada satu nilai sentinel yang layak dihafal namanya: unknown_error_code, yang dikirim Sunra ketika sebuah prediction gagal tetapi tidak ada klasifikasi yang bisa dipulihkan untuknya.

Catatan migrasi: error bernilai null ketika tidak ada kesalahan

Berlaku sejak 17 Agustus 2026. Objek error kini memiliki satu representasi yang sama di semua kanal. Tiga perbedaan di antara kanal-kanal itu sudah hilang:
  • error bernilai null ketika prediction tidak gagal. GET /v1/predictions/{prediction_id} dulu menjawab dengan objek kosong — "error": {} — pada setiap prediction yang berhasil, yang masih mengantre, dan yang dibatalkan. Kini ia menjawab "error": null, persis seperti yang sudah dilakukan endpoint status antrean. Bila Anda menguji kekosongannya (Object.keys(response.error).length === 0), ganti dengan pemeriksaan null (response.error === null).
  • Kegagalan selalu membawa code dan message yang tidak kosong. Ketika sebuah kegagalan mencatat sesuatu yang tidak dapat kami klasifikasikan, kini Anda mendapat nilai sentinel unknown_error_code beserta pesan umum, alih-alih field yang hilang, kosong, atau bukan berupa string.
  • Kegagalan yang tercatat sebagai teks biasa sampai kepada Anda sebagai teks. Segelintir prediction dari April 2026 menyimpan kesalahannya sebagai string telanjang. GET /v1/predictions/{prediction_id} dulu membuangnya, dan endpoint status antrean dulu menggantinya dengan pesan sentinel; kini keduanya menerbitkannya sebagai message di bawah code: "unknown_error_code".
Tidak ada yang dihapus dan tidak ada field baru yang muncul: error memang sudah ada pada setiap respons tersebut, dan hanya nilainya yang berubah. Pengiriman webhook tidak tersentuh — bentuknyalah yang diikuti kanal-kanal lain — dan error tetap tidak muncul pada pengiriman succeeded, bukan dikirim sebagai null. Jendela kompatibilitas. Tidak ada masa emisi ganda; API berhenti menghasilkan "error": {} pada tanggal tersebut. Bila Anda memutar ulang atau memproses ulang payload yang Anda rekam sebelum tanggal itu, perlakukan null dan {} sebagai hal yang sama sampai data tersimpan itu habis masa pakainya.

Perubahan mendatang: sebagian kegagalan akan mendapat code yang lebih spesifik

Saat ini sebagian besar kegagalan dilaporkan sebagai service_provider_error, termasuk banyak yang sebenarnya bukan bersifat sementara dan bukan pula kesalahan penyedia. Seiring kami mengklasifikasikan penyedia satu per satu, kegagalan-kegagalan itu berpindah ke code yang benar-benar menggambarkannya:
  • penyedia yang secara deterministik menolak input Anda menjadi invalid_input (sebelumnya service_provider_error);
  • masalah di sisi Sunra, seperti endpoint yang salah konfigurasi atau akun kami pada penyedia, menjadi internal_server_error (sebelumnya service_provider_error);
  • file input yang tidak berhasil kami ambil menjadi invalid_input (sebelumnya internal_server_error).
Tidak ada code yang diganti nama atau dihapus, dan tidak ada nilai code baru yang diperkenalkan — kelima nilai di atas tetap merupakan himpunan lengkap dari code yang sudah terklasifikasi. Yang berubah adalah code mana yang diterima oleh sebuah kegagalan tertentu, dan perubahannya berlangsung bertahap, per penyedia. Jika kode Anda bercabang berdasarkan code, inilah saat yang tepat untuk memindahkan logika itu ke retryable dan reason, yang menggambarkan kegagalan secara langsung dan tidak terpengaruh oleh reklasifikasi ini.

Kesalahan permintaan API