---
url: 'https://www.corbado.com/id/blog/webauthn-errors'
title: 'Panduan Lengkap Kesalahan WebAuthn di Produksi (2026)'
description: 'Pelajari arti kesalahan WebAuthn umum seperti NotAllowedError dalam lingkungan produksi dan cara mengklasifikasikannya berdasarkan jenis operasi, pengaturan waktu, dan konteks platform.'
lang: 'id'
author: 'Vincent Delitz'
date: '2026-07-03T07:09:42.285Z'
lastModified: '2026-08-28T12:00:42.356Z'
keywords: 'kesalahan webauthn, NotAllowedError, AbortError, SecurityError, pemecahan masalah WebAuthn, klasifikasi kesalahan kunci sandi, ASAuthorizationError, Credential Manager, passkey, otentikasi'
category: 'WebAuthn Know-How'
---

# Panduan Lengkap Kesalahan WebAuthn di Produksi (2026)

## 1. Pengantar

Di lingkungan produksi, [kesalahan WebAuthn](https://www.corbado.com/id/blog/pemecahan-masalah-passkey-solusi)
membingungkan karena browser mengekspos sekumpulan kecil nama `DOMException` (seperti
`NotAllowedError`) yang dapat mewakili berbagai penyebab yang mendasarinya. Selain itu,
sebagian besar "kesalahan" - sering kali di atas 95% dalam penerapan
[kunci sandi](https://www.corbado.com/id/glossary/cda) skala besar yang dioptimalkan - sebenarnya merupakan
**perilaku yang diharapkan** (pengguna membatalkan prompt [kunci sandi](https://www.corbado.com/id/glossary/cda)
sistem operasi).

> Penting: Karena alasan privasi, browser tidak membedakan apakah pengguna aktif
> membatalkan atau tidak ada [kunci sandi](https://www.corbado.com/id/glossary/cda) yang ada. Namun, dalam
> beberapa situasi dan dengan cukup konteks, baik di web maupun di platform native,
> beberapa kasus ini dapat dibedakan menggunakan sinyal seperti pengaturan waktu.

Jika Anda menginginkan definisi kanonis untuk nama-nama ini, mulailah dengan
[MDN `DOMException`](https://developer.mozilla.org/en-US/docs/Web/API/DOMException). Untuk
kondisi spesifik WebAuthn yang mengarah ke pengecualian ini (dan yang wajib ditegakkan
oleh browser), lihat [spesifikasi Autentikasi Web W3C](https://www.w3.org/TR/webauthn-3/).

Jika Anda memperlakukan semua kesalahan sebagai "bug", Anda akan melakukan hal yang salah:

- Anda akan mencemari metrik kesalahan Anda dengan pembatalan normal
- Anda akan melewatkan regresi nyata yang tersembunyi di dalam banyaknya `NotAllowedError`
- Anda akan mengirimkan UI yang membingungkan pengguna alih-alih membantu mereka
  memulihkan diri

Dalam artikel ini kami menjawab:

- Apa arti nama [kesalahan WebAuthn](https://www.corbado.com/id/blog/pemecahan-masalah-passkey-solusi) yang
  paling umum di lalu lintas nyata?
- Bagaimana Anda membedakan `NotAllowedError` ke dalam keranjang yang dapat
  ditindaklanjuti (batal vs waktu habis vs ketersediaan)?
- Mengapa kesalahan yang sama berarti hal yang berbeda bergantung pada operasi (login UI
  bersyarat vs login modal vs
  [pembuatan kunci sandi](https://www.corbado.com/id/blog/praktik-terbaik-pembuatan-passkey) vs pembuatan
  bersyarat)?
- Apa konteks minimum yang harus Anda tangkap sehingga "itu gagal" menjadi masalah yang
  dapat direproduksi?

## Key Facts

- `NotAllowedError` adalah **sinyal permukaan**, bukan akar penyebab. Ini bisa berarti
  pembatalan, waktu habis, "tidak ada kredensial lokal", atau tidak ada aktivasi pengguna
  tergantung pada konteks.
- **Tipe operasi mengubah maknanya.** `NotAllowedError` yang sama memiliki arti berbeda
  selama login UI bersyarat, login modal, pembuatan kunci sandi manual, pembuatan
  bersyarat dan penambahan yang dipicu otomatis.
- **Pengaturan waktu dari awal operasi** adalah sinyal yang paling diremehkan: segera
  (`<1 dtk`), pembatalan pengguna (1-15 dtk) dan waktu habis (30 dtk+) adalah kategori
  yang pada dasarnya berbeda.
- `AbortError` biasanya merupakan masalah siklus hidup/konkurensi (navigasi, render ulang,
  beberapa permintaan dalam proses).
- `SecurityError` hampir selalu konfigurasi/konteks dan langka dalam penerapan produksi
  yang matang.
- "Nama kesalahan browser" dan "penolakan verifikasi server" adalah lapisan yang berbeda.
  Lacak penolakan server sebagai kode eksplisit, bukan sebagai kegagalan klien generik.
- **Nama kesalahan mentah tidak dapat ditindaklanjuti secara langsung.** Selalu tangkap
  jenis operasi, pengaturan waktu dan konteks platform di samping `error.name` sehingga
  Anda dapat mengklasifikasikan kesalahan ke dalam keranjang yang benar-benar dapat Anda
  perbaiki.
- **"Lingkungan" lebih dari sekadar Browser + OS.** Untuk benar-benar memahami kesalahan,
  Anda harus melacak kombinasi penuh: Versi OS, Klien (Versi Browser/Aplikasi), Pengaturan
  Authenticator (misalnya, status iCloud/GPM) dan Model Perangkat Keras yang spesifik.
- **Kegagalan login adalah P1, kegagalan Pembuatan adalah P2.** Meskipun kesalahan
  pembuatan (P2) sering memiliki volume yang lebih tinggi karena pengguna meninggalkannya,
  kesalahan login (P1) memblokir akses dan memerlukan peringatan segera.

## 2. Lembar Panduan Produksi

Jika Anda hanya membutuhkan pemetaan cepat untuk membebaskan proses debug, mulailah dengan
tabel ini. Ini berpihak pada apa yang sebenarnya dilihat tim di dasbor dan tiket dukungan.

| **`error.name`**    | **Apa artinya biasanya di produksi**                                                                                                                                        | **Apa yang harus diperiksa untuk konfirmasi**                                                      | **Tindakan pertama (UX + teknis)**                                                                                 |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `NotAllowedError`   | Lembar penolakan pengguna, batas waktu terlampaui, atau ketidaksesuaian ketersediaan yang dikumpulkan menjadi satu. Ini merupakan keranjang kesalahan terbesar di produksi. | waktu ke kesalahan, apakah UI QR/hybrid muncul, apakah upacara dimulai dari tindakan pengguna asli | Perlakukan sebagai hal yang wajar: pulihkan UI + tunjukkan opsi alternatif                                         |
| `AbortError`        | Aplikasi Anda (atau browser) membatalkan upacara                                                                                                                            | navigasi/perenderan ulang selama upacara; panggilan WebAuthn serentak; `AbortController.abort()`   | Batasi pada satu permintaan serentak; cegah perubahan rute; tangani pembatalan sebagai alur kontrol wajar          |
| `SecurityError`     | Konteks/kebijakan tidak diizinkan                                                                                                                                           | asal + strategi ID RP; iframe/penyematan; HTTPS; kebijakan fitur                                   | Perbaiki ID RP/konfigurasi asal; validasi kebijakan penyematan; pastikan konteks yang aman                         |
| `InvalidStateError` | Ketidaksesuaian status (sering kali karena pendaftaran ganda)                                                                                                               | pendaftaran vs log masuk; `excludeCredentials`; ada kredensial yang sudah ada di pengautentikasi   | Anggap sebagai "sudah terdaftar"; sesuaikan rute UX; perbaiki pembuatan opsi                                       |
| `ConstraintError`   | Persyaratan tidak dapat dipenuhi                                                                                                                                            | `authenticatorAttachment`, `userVerification`, persyaratan kunci residen                           | Longgarkan pembatasan atau berikan opsi lain/alternatif. Contoh: Pengunci layar tidak ada pada Android             |
| `DataError`         | Input salah bentuk/tidak konsisten                                                                                                                                          | pengodean base64url; format id/tantangan/penangan pengguna                                         | Perbaiki pengodean/serialisasi; tambahkan validasi pada pembuatan opsi                                             |
| `NotSupportedError` | Platform/browser tidak mendukung permintaan Anda                                                                                                                            | versi OS/browser; asumsi pendeteksian fitur                                                        | Langsung gunakan alternatif; catat bagiannya; hindari menampilkan CTA passkey pada lingkungan yang tidak mendukung |
| `UnknownError`      | Platform/pengautentikasi gagal secara umum                                                                                                                                  | lonjakan setelah pembaruan OS; build perangkat; masalah dengan penyedia kredensial-manajer         | UX yang dapat dicoba lagi; catat nomor build; cari tahu lebih lanjut mengenai lonjakan pada bagian tertentu        |

Satu hal yang mudah terlewatkan: `error.name` yang sama bisa berarti hal yang sangat
berbeda bergantung pada **tipe operasi**. Tetap ingat konteks operasi saat Anda membaca
bagian di bawah ini. Praktiknya, kesalahan
[pembuatan kunci sandi](https://www.corbado.com/id/blog/praktik-terbaik-pembuatan-passkey) (pendaftaran) biasanya
jauh melebihi jumlah kesalahan login - tabel di atas berlaku untuk keduanya, tetapi
pembuatan adalah tempat sebagian besar volume berada.

Selanjutnya, kita akan membahas lebih dalam `NotAllowedError` karena itu adalah salah satu
yang paling sering Anda lihat dan yang sering salah diartikan tim.

## 3. NotAllowedError: Operasi habis waktu atau tidak diizinkan

`NotAllowedError` sering terlihat seperti
"[kunci sandi gagal](https://www.corbado.com/id/blog/mengapa-implementasi-kunci-sandi-gagal)", tetapi biasanya
itu adalah platform yang memberi tahu Anda bahwa pengguna tidak menyelesaikan UI OS.
Kuncinya adalah membaginya menjadi keranjang yang dapat Anda tindaklanjuti.

**Apa yang akan Anda lihat di konsol browser:**

| **Sumber**     | **Pesan kesalahan**                                                                                                                                  |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Chrome, Edge   | `NotAllowedError: The operation either timed out or was not allowed. See: https://www.w3.org/TR/webauthn-2/#sctn-privacy-considerations-client.`     |
| Safari, WebKit | `NotAllowedError: The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission.` |
| Safari, WebKit | `NotAllowedError: This request has been cancelled by the user.`                                                                                      |
| Chrome, Edge   | `NotAllowedError: The operation is not allowed at this time because the page does not have focus.`                                                   |
| Safari, WebKit | `NotAllowedError: The document is not focused.`                                                                                                      |
| Firefox        | `NotAllowedError: Operation failed.`                                                                                                                 |

Semua ini muncul sebagai `error.name === "NotAllowedError"`. `error.message` berbeda
menurut mesin browser dan penyebab yang mendasari, namun hasilnya sama: upacara tidak
selesai.

Ini berlaku untuk **login dan pembuatan kunci sandi**. Selama login (UI bersyarat, modal
dengan atau tanpa daftar yang diizinkan), `NotAllowedError` biasanya berarti pengguna
tidak menyelesaikan upacara. Selama
[pembuatan kunci sandi](https://www.corbado.com/id/blog/praktik-terbaik-pembuatan-passkey), kesalahan yang sama
muncul karena alasan yang berbeda: pengguna mengabaikan dialog pembuatan (pembuatan
bersyarat tidak berfungsi, atau halaman kehilangan fokus selama penambahan yang dipicu
secara otomatis. Tipe operasi mengubah makna kesalahan dan apa yang harus Anda lakukan
tentangnya.

**Pengaturan waktu sering kali merupakan sinyal yang diremehkan.** Kegagalan setelah
kurang dari satu detik klik adalah biasanya penolakan langsung (lingkungan tidak bisa
melakukannya, dokumen tidak difokuskan, kemampuan hilang). Kesalahan setelah beberapa
detik adalah pembatalan pengguna (mereka melihat dialog dan memutuskan untuk tidak
melanjutkan). Kesalahan setelah 30+ detik adalah batas waktu. Pada platform native,
pengaturan waktu sangat penting: perjalanan autentikator pulang pergi, prompt biometrik
dan penyerahan pengelola kredensial semuanya memiliki durasi karakteristik yang membantu
Anda memisahkan "tidak berfungsi" dari "pengguna pergi". Anda masih tidak dapat
membedakannya dengan mudah jika kunci sandi ada.

### 3.1 Disambiguate with Context

Anda tidak memerlukan sinyal yang sempurna. Anda memerlukan konteks yang cukup untuk
menghindari memperlakukan setiap `NotAllowedError` dengan cara yang sama.
[iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios)/Safari mendapatkan perhatian khusus di bawah ini
karena ia memiliki kendala unik (persyaratan aktivasi pengguna di versi sebelumnya), namun
dalam volume kesalahan mentah,
[Windows](https://www.corbado.com/id/blog/cara-menghapus-kunci-sandi-apple-windows-android) dan Chromium browsers
sering menghasilkan lebih banyak `NotAllowedError` daripada platform lainnya.
Sinyal-sinyal ini sering membuat Anda mendapatkan 80% dari cara:

| **Sinyal**                                                   | **Kemungkinan arti**                                                                                                                                                                                                                                                                                                                         | **Apa yang harus dilakukan selanjutnya**                                                                                                                                             |
| ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Kegagalan langsung (`<1 dtk`)                                | Penolakan lingkungan: tidak ada kemampuan, dokumen tidak fokus, permukaan pembuatan bersyarat tidak tersedia                                                                                                                                                                                                                                 | Periksa deteksi fitur; pastikan dokumen memiliki fokus; pastikan operasi didukung di platform ini                                                                                    |
| Pembatalan cepat (1-3 dtk)                                   | Perintah kejutan / tidak ada konteks                                                                                                                                                                                                                                                                                                         | Ubah waktu perintah; tambahkan waktu henti setelah pembatalan                                                                                                                        |
| Pembatalan sepanjang pengguna (3-15 dtk)                     | Pengguna melihat dialog dan memilih untuk tidak melanjutkan                                                                                                                                                                                                                                                                                  | UX yang Diharapkan; pulihkan UI + tunjukkan fallback                                                                                                                                 |
| Batas waktu (30 dtk+)                                        | Upacara habis waktu tanpa tindakan pengguna                                                                                                                                                                                                                                                                                                  | Keranjang sebagai "tidak selesai"; pertimbangkan apakah perintah tersebut diperhatikan                                                                                               |
| UI QR/hybrid muncul sebelum kegagalan                        | Tidak ada kredensial lokal yang tersedia di perangkat ini. Catatan: secara andal mendeteksi keputusan kode QR sebelum hal tersebut terjadi memerlukan [intelijen kunci sandi](https://docs.corbado.com/corbado-connect/features/passkey-intelligence) yang mengetahui apakah terdapat kredensial yang dapat digunakan di perangkat saat ini. | Batasi penawaran kunci sandi; buat "Gunakan ponsel" eksplisit; kurangi kejutan QR                                                                                                    |
| Terkonsentrasi di iOS/Safari dan terpicu tanpa klik/ketuk    | Aktivasi pengguna tidak ada                                                                                                                                                                                                                                                                                                                  | Mulai upacara dari gerakan pengguna sungguhan                                                                                                                                        |
| Saat pembuatan bersyarat atau tambahan yang terpicu otomatis | Isi otomatis tidak tersedia, kredensial sudah ada, atau halaman kehilangan fokus. Kesalahan pembuatan bersyarat dapat muncul tiba-tiba dan dalam volume tinggi ketika fitur diluncurkan, sehingga menjadikannya salah satu sumber kesalahan terbesar dalam semalam.                                                                          | Lihat pembuatan bersyarat; periksa status visibilitas dokumen; gunakan `getClientCapabilities()` untuk memverifikasi dukungan `conditionalCreate` sebelum mencoba panggilan tersebut |

Inilah juga mengapa `NotAllowedError` jarang terlihat oleh pengguna. Ini bukan pesan yang
dapat ditindaklanjuti oleh pengguna.

Klasifikasi konteks juga merupakan titik pembagian tingkat keberhasilan secara tajam.
[Analisis tingkat keberhasilan autentikasi kunci sandi Tolok Ukur Kunci Sandi Corbado 2026](https://www.corbado.com/passkey-benchmark-2026/passkey-authentication-success-rate)
mengukur penyelesaian Q1 2026 sebesar 55–95% untuk alur pengidentifikasi-pertama perangkat
yang tidak dikenal versus 95–99% untuk pengembalian perangkat yang dikenal di seluruh
penerapan B2C skala besar. Pengidentifikasi-pertama web
[iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios) mendarat di penyelesaian 85–95% (%
[CDA](https://www.corbado.com/id/glossary/cda) 0–5%), web [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) pada
70–85% (% [CDA](https://www.corbado.com/id/glossary/cda) 5–10%) dan web macOS pada 70–85% (%
[CDA](https://www.corbado.com/id/glossary/cda) 10–15%), sementara web
[Windows](https://www.corbado.com/id/blog/cara-menghapus-kunci-sandi-apple-windows-android) duduk di 45–60%
penyelesaian pengidentifikasi-pertama dengan % CDA di 55–65% pada
[Windows 11](https://www.corbado.com/blog/passkeys-windows-11) dan 40–55% pada
[Windows](https://www.corbado.com/id/blog/cara-menghapus-kunci-sandi-apple-windows-android) 10. Membaca volume
`NotAllowedError` tanpa memisahkan konteks perangkat yang dikenal versus perangkat yang
tidak dikenal menggabungkan dua rezim keberhasilan yang secara mendasar berbeda.

Satu nuansa yang penting dalam produksi: beberapa
[user agent](https://www.corbado.com/blog/client-hints-user-agent-chrome-safari-firefox) dapat memunculkan batas
waktu sebagai `TimeoutError`, namun banyak tim masih melihat batas waktu mengerucut
menjadi `NotAllowedError` di dasbor. Bagaimanapun, perlakukan batas waktu sebagai “upacara
tidak selesai” dan kelompokkan menggunakan waktu beserta konteks.

### 3.2 Penanganan UX: buat Pembatalan menjadi Keluar normal

Ketika lembar OS diabaikan atau habis waktunya, UI Anda harus segera pulih dan bereaksi
dengan baik. Serangkaian aturan praktis:

- kembalikan UI masuk (jangan ada pemutar yang terus berjalan)
- pertahankan status pengenal (jangan memaksa masuk kembali)
- tampilkan alternatif yang terlihat di layar yang sama
- hindari spanduk menakutkan untuk hasil yang diharapkan

Di luar hal dasar:

- Perlakukan pembatalan pertama sebagai hal biasa dan tawarkan opsi coba lagi dengan
  penjelasan yang tenang. Hanya setelah pembatalan kedua Anda harus menyarankan opsi
  alternatif (lihat cadangan dan
  [pemulihan kunci sandi](https://www.corbado.com/id/blog/pemulihan-kunci-sandi-fallback)).
- Izinkan maksimal tiga prompt pembuatan sebelum jeda waktu agar pengguna yang terkejut
  mendapat kesempatan kedua (lihat praktik terbaik pembuatan kunci sandi).
- Pisahkan jumlah kesalahan antara pembuatan dan masuk agar Anda membandingkan apel dengan
  apel.
- Kelompokkan tingkat kesalahan berdasarkan OS, browser, dan perangkat agar Anda dapat
  melihat di mana sebenarnya hambatan terjadi (lihat praktik terbaik masuk kunci sandi).

Jika "pembatalan" Anda benar-benar tinggi, langkah selanjutnya adalah memperbaiki akar
masalah di baliknya: waktu perintah, kejutan QR, dan ketersediaan yang rendah.

### 3.3 Perbaikan Teknik yang mengurangi NotAllowedError

Mulai dengan perubahan yang memindahkan metrik dengan cepat:

- Perbaiki pengaturan waktu perintah dan aktivasi pengguna (terutama pada
  [iOS](https://www.corbado.com/blog/how-to-enable-passkeys-ios)/Safari): Kejadian yang diaktifkan pengguna
  WebAuthn Safari.
- Kurangi kejutan QR/hybrid: mengapa alur passkey menunjukkan
  [kode QR](https://www.corbado.com/id/blog/kode-qr-login-autentikasi) dan pengguna meninggalkannya.
- Batasi tawaran agar passkey ditampilkan saat kemungkinan besar berhasil: tawarkan
  passkey hanya bila kemungkinan besar akan berhasil.
- Gunakan pola yang menghindari permintaan saat tidak ada kredensial lokal: Mediasi segera
  WebAuthn.
- **Tangani Ketidakstabilan Jaringan:** Kesalahan jaringan selama verifikasi sering kali
  terwujud sebagai kegagalan klien yang generik. Terapkan antrean offline untuk pencatatan
  telemetri Anda sehingga Anda tidak kehilangan data kesalahan saat koneksi pengguna
  terputus selama upacara berlangsung.
- **Batasi upacara dengan API deteksi** sehingga kegagalan lingkungan tidak
  menggelembungkan keranjang `NotAllowedError` Anda. Mulai dengan `isUVPAA()` sebagai
  pembatas paling dasar, lalu gunakan `getClientCapabilities()` untuk pemeriksaan yang
  lebih baik (pembuatan bersyarat, penerimaan bersyarat, transportasi hybrid,
  pengautentikasi platform). Perhatikan bahwa API deteksi dapat rusak pada pembaruan OS:
  [iOS 26](https://www.corbado.com/blog/ios-26-passkeys).2 meluncurkan bug WebKit di mana `isUVPAA()`
  menghasilkan `false` pada semua browser berbasis [WKWebView](https://www.corbado.com/blog/native-app-passkeys)
  meskipun passkey berfungsi dengan baik, menyebabkan lonjakan `NotAllowedError` mendadak
  bagi 10-25% pengguna iOS (lihat memperbaiki deteksi passkey dengan
  [getClientCapabilities](https://www.corbado.com/blog/webauthn-client-capabilities)()).

### 3.4 Catatan mengenai Nama Kesalahan yang berkembang

Nama-nama kesalahan adalah target yang bergerak. Ada berbagai proposal berkelanjutan untuk
menambah rincian [kesalahan WebAuthn](https://www.corbado.com/id/blog/pemecahan-masalah-passkey-solusi)
(misalnya, untuk memisahkan “tidak ada kredensial yang tersedia” dari “pengguna yang
membatalkan”). Sejak Februari 2026, hal tersebut belum diterapkan di dalam sebagian besar
peramban, jadi ada baiknya membangun keranjang alasan Anda sendiri berdasarkan konteks dan
waktu. Bila Anda ingin melacak pekerjaan ini, lihat
[WebAuthn issue #2062](https://github.com/w3c/webauthn/issues/2062) dan
[penjelas "Kode Kesalahan Baru"](https://github.com/w3c/webauthn/wiki/Explainer%3A-New-Error-Codes-%282024-Edition%29).

Nama-nama kesalahan lainnya kurang sering terjadi namun tetap berguna untuk dipahami bila
muncul.

## 4. AbortError: Operasi dibatalkan

`AbortError` tidak umum dalam volume jika dibandingkan dengan `NotAllowedError`, tetapi
saat muncul ini sangat diagnostik: ini biasanya berarti upacara tidak selesai karena
aplikasi Anda membatalkan permintaan - navigasi terjadi, state berubah, atau permintaan
kedua dimulai.

**Apa yang akan Anda lihat di konsol browser:**

| **Sumber**     | **Pesan kesalahan**                                       |
| -------------- | --------------------------------------------------------- |
| Chrome, Edge   | `AbortError: The operation was aborted.`                  |
| Chrome, Edge   | `AbortError: Aborted by AbortSignal.`                     |
| Firefox        | `AbortError: signal is aborted without reason`            |
| Firefox        | `AbortError: Operation timed out.`                        |
| Safari, WebKit | `AbortError: The user aborted a request.`                 |
| Chrome         | `AbortError: CredentialContainer request is not allowed.` |

Penyebab umum produksi meliputi:

- beberapa panggilan WebAuthn serentak (dua prompt balapan)
- perubahan rute/perenderan ulang saat upacara yang sedang berlangsung
- memanggil `AbortController.abort()` selama pencobaan ulang atau pembersihan status

Untuk memperbaikinya, berfokuslah untuk menjadikan upacara sebagai "bagian kritis":

- hanya bolehkan satu permintaan dalam proses secara bersamaan
- blokir navigasi selama upacara (atau batalkan secara bersih dan pulihkan UI)
- perlakukan pembatalan sebagai aliran kendali yang diharapkan: tampilkan tombol coba lagi
  dan [metode alternatif](https://www.corbado.com/id/faq/masuk-perangkat-kedua-kunci-sandi-terikat-perangkat)

Jika Anda melihat `AbortError` terkonsentrasi di permukaan yang disematkan atau aplikasi
multimesin, hal berikutnya yang harus diperiksa adalah `SecurityError`.

## 5. SecurityError: WebAuthn tidak didukung pada situs dengan kesalahan sertifikat TLS

`SecurityError` adalah browser yang memberitahu Anda: "konteks ini tidak diizinkan untuk
melakukan yang Anda minta." Dalam praktik, hampir selalu soal konfigurasi, bukan perilaku
pengguna. Pada pengerahan produksi yang sudah matang, `SecurityError` langka terjadi
karena masalah ini umumnya sudah tertangkap saat tes integrasi. Jika ini muncul di
produksi, umumnya hal ini berarti ada penambahan domain baru, penyematan konteks, atau
sasaran pengerahan yang dilakukan tanpa konfigurasi WebAuthn yang tepat.

Penyebab-penyebab umum termasuk:

- RP ID / kegagalan kecocokan muasal (setelan multi-domain)
- larangan penyematan asalan-bersilang (iframe)
- konteks tidak aman (bukan HTTPS) atau terblokirnya hak/kebijakan
- `.well-known/webauthn` atau `.well-known/assetlinks.json` salah konfigurasi, hilang,
  atau tidak tersedia sementara. Isu jaringan saat terjadi kondisi krusial yang saat mana
  browser mengambil berkas-berkas ini bakal menimbulkan kegagalan. Satu rupa buta yang
  umum: jika halamamuka Anda turun untuk di-maintenance, berkas-berkas well-known juga
  ikutan offline, lantas merusak perayaan kunci sandi lintas seluruh pihak-tergantung yang
  memerlukannya.

**Apa yang bakal Anda lihat dalam konsol browser:**

| **Sumber**      | **Pesan galat**                                                                                                                  |
| --------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Chrome, Edge    | `SecurityError: WebAuthn is not supported on sites with TLS certificate errors.`                                                 |
| Any browser     | `SecurityError: The relying party ID is not a registrable domain suffix of, nor equal to the current origin's effective domain.` |
| Chrome (iframe) | `SecurityError: The 'publickey-credentials-create' feature is not enabled in this document.`                                     |

Dalam produksi, `SecurityError` langka terjadi - ini lumrah tertangkap saat tes integrasi.
Ketika ini terjadi, kesalahan sertifikat TLS yang paling umum bertahan hidup.

Loop debugging paling cepat adalah:

- masuk pada asal dan RP ID masukan yang Anda gunakan
- perbanyak dalam konteks sama (top-level vs [iframe](https://www.corbado.com/blog/iframe-passkeys-webauthn),
  prod domain vs staging)
- jika Anda menyematkan log-masuk, tetapkan kebijakan izin sudah di-setel (misalnya
  `publickey-credentials-create` / `publickey-credentials-get`):
  [MDN Permissions-Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Headers/Permissions-Policy/publickey-credentials-create)
- pastikan taktik domain Anda (lihat asal berkaitan)
- jika Anda memakai [iframe](https://www.corbado.com/blog/iframe-passkeys-webauthn), validasi kebijakan fiturnya
  (lihat kunci sandi [iframe](https://www.corbado.com/blog/iframe-passkeys-webauthn))

Setelah `SecurityError` di-urus, wadah selanjutnya yang patut ditangani secara serius
adalah rangkaian kesalahan yang menandakan bug penerapan: `InvalidStateError`,
`ConstraintError` serta `DataError`.

## 6. InvalidStateError, ConstraintError, DataError: perlakukan sebagai Bug Implementasi

Kesalahan-kesalahan ini harus langka dalam
[implementasi kunci sandi](https://www.corbado.com/id/blog/passkey-day-2-problems) yang matang. Jika muncul,
mereka biasanya menunjukkan bahwa opsi generasi salah untuk suatu segmen atau aliran ada
dalam keadaan salah.

### 6.1 InvalidStateError: "kredensial sudah terdaftar pada relying party"

**Apa yang akan Anda lihat di konsol browser:**

| **Sumber**     | **Pesan kesalahan**                                                                                                                                  |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Safari, WebKit | `InvalidStateError: The user attempted to register an authenticator that contains one of the credentials already registered with the relying party.` |
| Chrome, Edge   | `InvalidStateError: At least one credential matches an entry of the excludeCredentials list in the platform attached authenticator.`                 |
| Chrome, Edge   | `InvalidStateError: A request is already pending.`                                                                                                   |
| Firefox        | `InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable`                                                       |

Arti tipikal:

- pendaftaran: Anda mencoba untuk membuat kredensial yang sudah ada (duplikat)
- log masuk: kurang umum; seringkali berarti alur/keadaan inkonsisten untuk platform
  tersebut

Penanganan praktis:

- jika terjadi pada registrasi manual, perlakukan sebagai "sudah terdaftar" dan rutekan
  secara tepat
- pastikan `excludeCredentials` mencantumkan seluruh ID kredensial eksisten untuk pengguna
  sehingga autentikator dapat mendeteksi duplikat (lihat
  [excludeCredentials](https://www.corbado.com/glossary/excludecredentials))
- selama pembuatan kondisional, `InvalidStateError` merupakan harapan dan sebaiknya
  diabaikan dalam diam: artinya sebuah kunci sandi sudah eksis dalam provider. Hal yang
  sama juga berlaku untuk `NotAllowedError` dan `AbortError` selama pembuatan kondisional
  (lihat
  [conditional create on Chrome](https://developer.chrome.com/docs/identity/webauthn-conditional-create))

### 6.2 ConstraintError

Arti Umum: [authenticator](https://www.corbado.com/glossary/authenticator) tidak dapat memenuhi kendala yang Anda
minta.

Pemicu umum:

- penguncian layar perangkat hilang (terutama
  [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android)): platform membutuhkan verifikasi
  biometrik atau PIN, tetapi perangkat tersebut tidak mempunyai layar kunci yang
  dikonfigurasi
- `authenticatorAttachment` terlalu ketat atau [kunci residen](https://www.corbado.com/id/glossary/ctap) asumsi
- kendala `userVerification` pada segmen-segmen di mana hal tersebut tidak tersedia

Memperbaiki: ringankan kendala (jika dimungkinkan) atau tawarkan rute alternatif. Untuk
layar kunci yang hilang, pertimbangkan pendeteksian kondisi ini lalu arahkan user
ketimbang membiarkan kegagalan berlalu tanpa notifikasi (Android).

### 6.3 DataError

Arti khas: masukan tidak berbentuk dengan baik atau inkonsisten.

Pemicu yang lazim:

- kesalahan pada saat penyandian (base64 vs base64url)
- id kredensial yang cacat / tantangan pada pemformatan

Solusi: validasi dan normalisasi masukan di perbatasan tempat Anda mengonfigurasi WebAuthn
opsional. Dalam penerapannya, `DataError` secara praktis ditiadakan di dalam platform
sistem pengerjaan—seandainya pembuatan pilihan Anda telah diuji, Anda takkan melihatnya di
panel informasi Anda.

Kala semua kesalahan ini ditangani, kendala berikutnya adalah tentang jangkauan: apakah
user tak dapat menaut karena gawai yang dipakai tidak sesuai dengan dukungan WebAuthn yang
Anda rancang?

## 7. NotSupportedError: Agen pengguna tidak mendukung kredensial kunci publik

`NotSupportedError` adalah sinyal cakupan, bukan sinyal keandalan. Biasanya ini berarti
suatu segmen tidak dapat melakukan apa yang Anda minta (versi OS/browser terlalu lama,
kemampuan tidak ada, fitur tidak diaktifkan).

**Apa yang akan Anda lihat di konsol browser:**

| **Sumber**            | **Pesan kesalahan**                                                                            |
| --------------------- | ---------------------------------------------------------------------------------------------- |
| Chrome, Edge          | `NotSupportedError: The user agent does not support public key credentials.`                   |
| Firefox               | `NotSupportedError: Resident credentials or empty 'allowCredentials' lists are not supported.` |
| Chrome, Edge, Firefox | `TypeError: PublicKeyCredential.parseCreationOptionsFromJSON is not a function`                |
| Chrome, Edge, Firefox | `TypeError: PublicKeyCredential.parseRequestOptionsFromJSON is not a function`                 |
| Chrome, Edge, Firefox | `TypeError: credential.toJSON is not a function`                                               |
| Safari                | `TypeError: Can only call PublicKeyCredential.toJSON on instances of PublicKeyCredential`      |

Dua hal pertama adalah DOMException `NotSupportedError` asli. Entri `TypeError` secara
teknis adalah tipe pengecualian yang berbeda tetapi mewakili kelas masalah yang sama:
browser atau lingkungan tidak mendukung apa yang Anda minta. Rumpun `TypeError`
serialisasi JSON jauh lebih umum dalam praktiknya daripada DOMException
`NotSupportedError` itu sendiri (lihat di bawah).

Penyebab umum meliputi:

- versi browser/OS lama yang tidak mendukung dasar WebAuthn
- meminta fitur WebAuthn yang tidak tersedia di platform tersebut
- mencoba alur platform-spesifik di perangkat yang tidak didukung

**Rumpun serialisasi JSON adalah sumber terbesar dari kegagalan kelas `NotSupportedError`
di produksi.** Secara teknis ini muncul sebagai `TypeError` (metode hilang), bukan sebagai
`DOMException`, tetapi di sinilah Anda akan menemukannya. Dua penyebab dasar berbeda:

1. **Browser tidak mendukung metode serialisasi JSON WebAuthn.** Browser memiliki
   `navigator.credentials` tetapi bukan `PublicKeyCredential.parseCreationOptionsFromJSON`
   / `parseRequestOptionsFromJSON`. Ini merupakan sekitar 90% dari rumpun kesalahan ini,
   terkonsentrasi pada versi Safari dan Chrome lama. Jika perpustakaan klien Anda
   bergantung pada metode ini tanpa cadangan, ini menghasilkan volume kesalahan yang
   signifikan.
2. **Ekstensi pengelola kata sandi merusak `.toJSON()`.** Ekstensi seperti
   [Bitwarden](https://www.corbado.com/blog/passkey-analysis-bitwarden-developer-survey-2024),
   [LastPass](https://www.corbado.com/blog/lastpass-data-breach), atau
   [1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis) dapat mencegat upacara
   dan mengembalikan objek yang terlihat seperti kredensial tetapi bukan instance
   `PublicKeyCredential` yang sebenarnya. Memanggil `.toJSON()` padanya akan gagal,
   mengembalikan tidak terdefinisi, atau objek tersebut `null` seluruhnya. Ini adalah
   sekitar 10% dari rumpun tetapi terutama membingungkan untuk debug karena pesan
   kesalahan berbeda menurut browser (Safari: "Can only call on instances of
   PublicKeyCredential"; Firefox: "does not implement interface PublicKeyCredential").

Penanganan harus tegas dan cepat:

- segera kembali ke [kata sandi](https://www.corbado.com/id/blog/cara-mengaktifkan-passkey-android)/OTP cadangan
- catat segmen sehingga Anda dapat mengukur kesenjangan cakupan
- hindari menampilkan CTA passkey pada segmen yang akan selalu gagal

Jika cakupan terlihat baik tetapi kegagalan masih terjadi pada segmen tertentu, Anda
mungkin menghadapi masalah lapisan platform yang muncul sebagai `UnknownError`.

## 8. UnknownError: Terjadi kesalahan yang tidak diketahui saat berbicara dengan pengelola kredensial

`UnknownError` adalah serba-bisa untuk kegagalan autentikator/OS yang tidak dipetakan
secara jelas ke dalam kategori lain. Ini sering kali sementara, tetapi juga dapat melonjak
setelah pembaruan OS.

**Apa yang akan Anda lihat di konsol browser:**

| **Sumber**         | **Pesan kesalahan**                                                                                                                     |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| Chrome (Android)   | `UnknownError: An unknown error occurred while talking to the credential manager.`                                                      |
| Browser apa saja   | `UnknownError: The operation failed for an unknown transient reason.`                                                                   |
| Browser apa saja   | `UnknownError: Either the device has received unexpected request data, or the device has been reconfigured since the request was made.` |
| Browser apa saja   | `UnknownError: Something went wrong.`                                                                                                   |
| Chrome (LastPass)  | `TypeError: Cannot use 'in' operator to search for 'type' in null`                                                                      |
| Safari (LastPass)  | `TypeError: null is not an Object. (evaluating 'key in input')`                                                                         |
| Chrome (Bitwarden) | `FallbackRequested`                                                                                                                     |

Penanganan praktis:

- gunakan UX yang ramah untuk mencoba lagi (jangan "menyalahkan pengguna")
- ambil OS/nomor build dan konteks credential-manager/provider di mana dimungkinkan
- waspadai lonjakan spesifik segmen setelah pembaruan OS

Satu sumber kesalahan yang unik dan tidak masuk secara rapi ke dalam kategori
`DOMException` mana pun: **ekstensi browser manajer kata sandi** (seperti
[Bitwarden](https://www.corbado.com/blog/passkey-analysis-bitwarden-developer-survey-2024),
[LastPass](https://www.corbado.com/blog/lastpass-data-breach),
[1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis), dan lain-lain) dapat
mencegat panggilan API WebAuthn dan mengembalikan tanggapan non-standar. Meskipun kecil
dalam volume dibandingkan dengan pembatalan pengguna, kesalahan ini berharga untuk dilacak
karena mereka memengaruhi segmen pengguna tertentu secara konsisten dan gejala-gejalanya
membingungkan: metode yang hilang dari objek kredensial yang dikembalikan, tipe kesalahan
yang tidak terduga, atau tanggapan cacat yang tidak cocok dengan satupun kesalahan
WebAuthn yang terdokumentasi. Kesalahan-kesalahan ini sering kali timbul sebagai
`UnknownError` atau sebagai pengecualian yang tidak terklasifikasi. Jika Anda melihat
adanya lonjakan kesalahan yang terkonsentrasi di dalam peramban tertentu tanpa alasan dari
OS itu sendiri, periksa apakah suatu ekstensi manajer kredensial terkait.

Selama ini kami hanya meliputi penamaan kesalahan penjelajah peramban saja. Tetapi jika
Anda juga mengekspor aplikasi lokal, maka pemandangan kesalahan pun turut menjadi lain -
serta dalam sedikit hal, lebih berarti.

## 9. Sepatah Kata mengenai Aplikasi native (iOS dan Android)

Segala hal di atas mencakup peramban web.
[Aplikasi native](https://www.corbado.com/id/blog/webauthn-relying-party-id-rpid-kunci-sandi) - iOS dengan rangka
ASAuthorization, [Android](https://www.corbado.com/blog/how-to-enable-passkeys-android) beserta Manajer
Kredensial - membagikan rumpun kesalahan sama pada kategori dasar mereka melainkan agak
sedikit berbeda dalam arti yang lebih luas:

1. **"Tidak ada kredensial" adalah sinyal yang berbeda.** Di web, peramban menyatukan
   "tidak ada kredensial yang tersedia" dan "pengguna membatalkan" ke dalam
   `NotAllowedError` yang sama demi privasi. Di ranah native, menggunakan
   `preferImmediatelyAvailableCredentials` di iOS (`ASAuthorizationController`) atau
   `setPreferImmediatelyAvailableCredentials(true)` di Android (`GetCredentialRequest`)
   akan memberitahukan OS hanya untuk menyajikan kredensial yang sudah ada di perangkat
   dan langsung gagal jika tidak ada kredensial tersebut. Ini memberi Anda kembalian
   "tanpa kredensial" yang bersih, sesuatu yang tidak dapat diberikan oleh web.

2. **Status penyedia kredensial tampak.** Platform native dalam beberapa kondisi dapat
   memberitahu Anda jika tidak ada penyedia kredensial (Google Password Manager,
   [iCloud Keychain](https://www.corbado.com/glossary/icloud-keychain),
   [1Password](https://www.corbado.com/blog/1password-passkeys-best-practices-analysis), dll.) yang dipasang,
   dikonfigurasi, atau disetel sebagai nilai default lalu bereaksi terhadapnya. Pada web,
   informasi ini tersembunyi di balik pesan buram `NotAllowedError`.

3. **Pesan kesalahan lebih spesifik.** Oleh karena sang pengguna telah memasang aplikasi
   tersebut - dan dengannya membuat satu hubungan kepecayaan dengan pihak terkait - maka
   OS memberi rincian diagnosisnya. Pertimbangan keprivasian yang secara paksa menekan
   peramban di web agar menyamarkan kesalahannya tidak berlaku sejalan kala pengaplikasian
   tersebut nyata sudah berada di gawai. iOS menyuguhkan pesan terlokalisasi di dalam
   gawai berdasarkan preferensi bahasa penggunanya. Android mengantarkan sejenis penataan
   struktur kesalahan lewat urutan permasalahannya. Karenanya perbaikan jauh lebih ringkas
   walaupun arti pada hal itu menuntun penanganan yang mengharuskan agar penyetelan dapat
   melokalisasi bentuk format kesalahan khas-platform.

### 9.1 iOS (Kerangka ASAuthorization)

iOS memunculkan [kesalahan kunci sandi](https://www.corbado.com/id/blog/pemecahan-masalah-passkey-solusi) melalui
kerangka ASAuthorization. Semua kesalahan tiba dalam callback delegasi
`authorizationController(controller:didCompleteWithError:)` sebagai objek `NSError`.

**Klasifikasikan berdasarkan domain + kode, bukan berdasarkan string pesan.** Domain
kesalahan utama adalah `com.apple.AuthenticationServices.AuthorizationError`
(`ASAuthorizationError.errorDomain`). Cast kesalahan dengan
`let nsError = error as NSError` dan cocokkan pada `.domain` dan `.code`. Jangan pernah
mencocokkan pada `.localizedDescription` di produksi - pesan-pesan
[Apple](https://www.corbado.com/id/blog/cara-menghapus-kunci-sandi-apple-windows-android) dilokalkan ke 30+
bahasa dan dapat berubah seiring versi OS. String pesan yang terdaftar di bawah ini
berguna untuk mengenali kesalahan dalam catatan (log), tetapi itu bukanlah kriteria
klasifikasi.

**Kode ASAuthorizationError Publik:**

| **Kode** | **Nama**                                | **Sejak** | **Apa artinya**                                                                                                                                                                                                                                                                                                                      |
| -------- | --------------------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| 1000     | `Unknown`                               | iOS 13    | Tidak boleh muncul dalam produksi. Hal umum untuk menangkap-semua.                                                                                                                                                                                                                                                                   |
| 1001     | `Canceled`                              | iOS 13    | Pengguna menepis lembaran passkey. Kesalahan terumum yang ada - setara `NotAllowedError`. Tanda bersih dengan `userInfo` kosong dan tiada kesalahan mendasar.                                                                                                                                                                        |
| 1002     | `InvalidResponse`                       | iOS 13    | Kerusakan tingkatan kerangka kerja. Langka dalam pengerjaannya.                                                                                                                                                                                                                                                                      |
| 1003     | `NotHandled`                            | iOS 13    | Tak ada provider yang menangani permintaan. Periksa setelan hak-guna serta provider.                                                                                                                                                                                                                                                 |
| 1004     | `Failed`                                | iOS 13    | Gagal pada umumnya. Terdapat keterangan nyata pada `localizedDescription` (semisal "Aplikasi beserta tanda kenal X tak bersangkut paut dengan ranah Y"). `userInfo` bisa menampung tulisan `FailureReason`, hanya saja tak selamanya `NSUnderlyingErrorKey` diisi - kegagalan penyatuan domain nihil nilainya bagi yang tersembunyi. |
| 1005     | `NotInteractive`                        | iOS 15    | Kredensial tidak sedia apabila menggunakan opsi preferImmediatelyAvailableCredentials\`. Hal begini tanda bersih "tak dijumpai" - kesetaraan iOS dari perihal "tiada passkey pada perangkat." Antar muka sama sekali tak dimunculkan.                                                                                                |
| 1006     | `MatchedExcludedCredential`             | iOS 18    | Passkey bagi RP peranti tersebut telah tersedia di dalamnya. Tanda jernih melacak gandaan - `userInfo` hampa, tanpa `NSUnderlyingErrorKey`. Tata urut berlaku walau tanpa menilik huruf.                                                                                                                                             |
| 1007     | `CredentialImport`                      | iOS 18.2  | Impor kredensial tak berhasil.                                                                                                                                                                                                                                                                                                       |
| 1008     | `CredentialExport`                      | iOS 18.2  | Ekspor kredensial tak berhasil.                                                                                                                                                                                                                                                                                                      |
| 1009     | `PreferSignInWithApple`                 | iOS 26    | Pemakai cenderung Memasuki sistem menggunakan layanan masuk dengan ID Apple alih-alih kunci aksesnya. Baru dalam rilis iOS kali ini.                                                                                                                                                                                                 |
| 1010     | `DeviceNotConfiguredForPasskeyCreation` | iOS 26    | Piranti kurang kata-sandi pembuka-layar maupun Keychain di lingkungan iCloud-nya. Inilah kelemahan simulator pada peluncuran OS kali ini: menampilkan ralat yang semestinya tak ada kendati kesemuanya beraturan dan beres (terbebas terhadap perangkat aslinya).                                                                    |

Perbedaan terpenting pada lingkungan produksi: **sejak dirilisnya sistem operasi teranyar
itu, jejak duplikasi mengirimkan notifikasi galatnya pribadi berkode 1006
(`MatchedExcludedCredential`).** Dalam penggunaan terdahulu di edisi sebelumnya, sisa
duplikat terbungkus jauh di bawah notifikasi `Failed` (1004). Kini pada platform teranyar
ini perbedaannya tersusun (kode yang beda) alih-alih cuma rentetan kalimat.

**Masalah umum di masa berjalannya sistem operasi (batas perinci-baca):**

Uraian-uraian ini menyingkap di `localizedDescription` serta `userInfo` buat kekhususan
aneka-salah . Memanfaatkan hal tersebut berguna di penapisan maupun pengusutan dan
penelusuran, walau tidak sepadan untuk pembagian berjenjang pada rancang kodenya.

| **Pesan (Lokal Bahasa Inggris)**                                                | **Kode dasar**  | **Catatan**                                                                                                                                                                           |
| ------------------------------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Application with identifier <TeamID.BundleID> is not associated with domain X` | 1004 (`Failed`) | Entitlement Associated Domains aplikasi tidak cocok dengan relying party. Perbaiki file `apple-app-site-association` di server Anda.                                                  |
| `Couldn't communicate with a helper application.`                               | 1004 (`Failed`) | Ekstensi penyedia kredensial gagal merespons. Sementara - percobaan ulang sudah tepat.                                                                                                |
| `Request already in progress for specified application identifier.`             | 1004 (`Failed`) | Permintaan ASAuthorization duplikat terkirim saat ada permintaan yang tertunda. Race condition di aplikasi.                                                                           |
| `Stolen Device Protection is enabled and biometry is required.`                 | 1004 (`Failed`) | Perlindungan Perangkat yang Dicuri di iOS 17+ memblokir autentikasi biometrik di lokasi asing. Tidak dapat ditindaklanjuti oleh pengembang, tetapi layak ditampilkan kepada pengguna. |
| `(AuthenticationServicesCore.ASCABLEClient.ClientError error 2.)`               | Domain terpisah | Jabat tangan Bluetooth autentikasi lintas perangkat (hybrid/CABLE) gagal.                                                                                                             |
| `(AuthenticationServicesCore.ASCABLEClient.ClientError error 3.)`               | Domain terpisah | Koneksi Bluetooth autentikasi lintas perangkat gagal.                                                                                                                                 |

**Pesan "tidak ada kredensial" lokal (kode 1005):**

Bila `preferImmediatelyAvailableCredentials` ditetapkan dan tak terdapat sandi, iOS
memberi kembalian galat berkode 1005 (`NotInteractive`) berwujud kabar terlokalkan ke
dalam bahasa asli sang pengguna yang tersetel pada gawai kepunyaannya. Cuma ini yang dapat
ditemui bagi perangkat tersemat secara bawan—mesin penjelajah pun urung memunculkannya
sekelumit juga. Keterangan tersebut senantiasa diawali kalimat
`The operation couldn't be completed.` (Bahasa Inggris) beriring teks tertata berdasarkan
lokalisasinya di antaranya:

| **Bahasa**             | **Pesan**                                                                            |
| ---------------------- | ------------------------------------------------------------------------------------ |
| Mandarin (Sederhana)   | `没有可用于登录的凭证。`                                                             |
| Vietnam                | `Không có sẵn thông tin để đăng nhập.`                                               |
| Arab                   | `لا تتوفر بيانات اعتماد لتسجيل الدخول.`                                              |
| Spanyol                | `No hay ninguna credencial disponible para iniciar sesión.`                          |
| Mandarin (Tradisional) | `沒有可用於登入的憑證。`                                                             |
| Korea                  | `로그인을 위한 자격 증명이 없습니다.`                                                |
| Prancis (Kanada)       | `Aucun identifiant disponible pour la connexion.`                                    |
| Portugis (Brasil)      | `Nenhuma credencial disponível para login.`                                          |
| Prancis (Prancis)      | `Aucune information d'identification n'est disponible pour procéder à la connexion.` |
| Thai                   | `ไม่มีข้อมูลประจำตัวสำหรับเข้าสู่ระบบ`                                               |
| Italia                 | `Non ci sono credenziali disponibili per l'accesso.`                                 |
| Belanda                | `Geen inloggegevens beschikbaar.`                                                    |
| Jepang                 | `ログイン用の資格情報がありません。`                                                 |
| Turki                  | `Oturum açmak için kullanılabilecek kimlik bilgisi yok.`                             |

Perangkat dengan lokal bahasa Inggris biasanya menyelesaikan "tidak ada kredensial" di
level API sebelum kerangka kerja ASAuthorization mengembalikan kesalahan yang dilokalkan,
itulah sebabnya tidak ada varian bahasa Inggris yang muncul di atas. Secara programatik,
selalu cocokkan pada kode 1005 daripada mengurai string ini.

### 9.2 Android (Credential Manager API)

Android memunculkan [kesalahan kunci sandi](https://www.corbado.com/id/blog/pemecahan-masalah-passkey-solusi)
melalui Credential Manager API (`androidx.credentials`). Pesan kesalahan mencakup pesan
utama dan sering kali sebuah `cause` dengan rincian tambahan. Dibandingkan dengan iOS,
Android memberikan tipe kesalahan yang lebih terstruktur dan penyebab yang lebih jelas
untuk masalah konfigurasi.

**Pembatalan pengguna dan deteksi kredensial:**

| **Kesalahan**                                     | **Catatan**                                                                                                                                                                                                          |
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `User cancelled the operation`                    | Pengguna membatalkan prompt passkey. Setara dengan `NotAllowedError`. Catatan: Credential Manager juga mengembalikan `User canceled the request` (ejaan AS) dari path kode yang berbeda - keduanya sama.             |
| `Excluded credential matches existing credential` | Passkey sudah ada untuk ID kredensial ini. Setara dengan `InvalidStateError`. Berbeda dengan iOS, pesannya terpisah dari pembatalan pengguna.                                                                        |
| `No create options available.`                    | Tidak ada penyedia kredensial yang memenuhi syarat yang dapat menangani permintaan pembuatan. Biasanya berarti Google Play Services sudah usang atau tidak ada penyedia kredensial yang mendukung pembuatan passkey. |

**Kesalahan konfigurasi dan keamanan:**

| **Kesalahan**                                                                  | **Catatan**                                                                                                                                                                                                                                                                    |
| ------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Passkeys not supported for this app`                                          | Digital Asset Links (`assetlinks.json`) tidak ada atau tidak memuat sidik jari sertifikat penandatanganan aplikasi. Setara dengan `SecurityError`.                                                                                                                             |
| `Https failed: respCode=301, url=https://<domain>/.well-known/assetlinks.json` | Berkas `assetlinks.json` mengembalikan redirect, bukan HTTP 200. Android mensyaratkan berkas ada di URL pasti tanpa pengalihan.                                                                                                                                                |
| `The incoming request cannot be validated`                                     | Credential Manager tidak dapat memverifikasi permintaan terhadap Digital Asset Links.                                                                                                                                                                                          |
| `RP ID cannot be validated.`                                                   | Identitas relying party pada opsi WebAuthn tidak sesuai dengan isi `assetlinks.json`.                                                                                                                                                                                          |
| `Screen lock is missing.`                                                      | Tidak ada PIN, pola penguncian maupun autentikasi biometrik pada setelan gawainya. Kunci-sandi butuh verifikasi pengguna. Setara perlakuan terhadap kendala galat atau constraint-nya.                                                                                         |
| `Cannot find an eligible account.`                                             | Tak sepotong nama pun dari sekian kumpulan pendaftaran atas dasar sistem buatan mbah "Google" itu memenuhi ketentuan persyaratan dalam hal mencetak maupun mengkaryakan anak kunci. Hal amat ganjil seperti langkanya pengerahan instalasi khusus kelas bisnis besar (custom). |

**Kesalahan platform dan autentikator:**

| **Kesalahan**                                                                            | **Catatan**                                                                                                                                                                                                                                                         |
| ---------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Unsuccessful result from folsom activity.`                                              | Kegagalan internal Google Play Services. "Folsom" adalah komponen GMS untuk operasi passkey. Bersifat sementara - coba lagi wajar dilakukan.                                                                                                                        |
| `Can't find the proper key to decrypt the private key from WebauthnCredentialSpecifics.` | Kunci sandi yang disinkronkan sudah ada tetapi peranti urung mendeskripsikan kunci asalnya di pihak internal Google Manager dengan keadaannya yang kacau. Sandinya sendiri diimpor bersilang kendati dekripsi-kuncinya tiada dapat diraih.                          |
| `Operation was interrupted` (cause: `The UI was interrupted - please try again.`)        | Antarmuka Pengelola Kredensial (Credential Manager) mendadak diselang/tumpang-tindihkan sama giat lain semisal seruan panggilan darurat atau penataan balik/pergantian hadap layar. Serupalah hal itu dengan peristiwa Abort Error (terhenti paksa).                |
| `Unknown credential error`                                                               | Sifat lazim jika urung diselidiki di rupa mana dan pada letak apanya si kutu keparat bermukim maupun bercokol pada sekuritas sang pengguna yang tidak mengatasnamakan bagian yang mana pun pada ralat. Semisal ralat pada penampungan sementara atau kilasan waktu. |
| `timeout` (cause: `Canceled`)                                                            | Upacara otentikasi di pengatur kredensial menampakkan sisa waktunya sebelum sang pelanggan menyelesaikan serangkaian langkah proses pengecekan berbasis keunikan pada biometrik maupun pengenal muka pada kamera selular pintar miliknya.                           |

## 10. Menyusun semuanya bersama: Taksonomi Kesalahan

Diagram berikut ini memperlihatkan bagaimana sekalian tata urutan mulai tingkat Papan
Prasarana (Sistem Utama) berujung deteksi hingga tingkatan Operasional terhubung utuh
berjenjang atas bawah pada bagannya masing-masing. Gambar bagan di bawah patutnya dibikin
konsep tata rancangnya kala berupaya dalam perekaman atas tiap-tiap notifikasi kesalahan
yang mengemuka saat terjadinya.

```mermaid
flowchart TD
    %% Global Styles
    classDef expected fill:#e3f2fd,stroke:#1565c0,stroke-width:2px;
    classDef unexpected fill:#ffebee,stroke:#c62828,stroke-width:2px;
    classDef network fill:#fff3e0,stroke:#ef6c00,stroke-dasharray: 5 5;
    classDef env fill:#f3e5f5,stroke:#7b1fa2,stroke-width:1px;
    classDef action fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px;

    %% --- LEFT SIDE: NETWORK & SERVER ---
    subgraph Infrastructure ["Infrastruktur (Server/Jaringan)"]
        direction TB
        ServerErr["Kesalahan Sisi Server<br/>500 / Kesalahan Logika"]:::network
        NetErr["Kesalahan Jaringan<br/>Batas Waktu / 400 Bad Request"]:::network

        ServerErr & NetErr -->|Terwujud sebagai| ClientManifest["Kesalahan Generik Sisi Klien"]
    end

    %% --- CENTER: THE ENVIRONMENT STACK (From Sketch) ---
    subgraph Environment ["Lingkungan (Sisi Klien)"]
        direction TB

        %% Layer 1: Platform Type
        subgraph Type ["Lapisan 1: Platform"]
            Web["Web / Browser"]
            Native["Native / Aplikasi"]
        end

        %% Layer 2: OS Context
        subgraph OS_Layer ["Lapisan 2: OS & Versi"]
            OS_Web["OS: Windows, macOS, Linux"]
            OS_Nat["OS: iOS, Android"]
            OS_Ver["Versi OS / Setelan<br/>(Kunci Layar, Biometrik)"]

            Web --> OS_Web
            Native --> OS_Nat
            OS_Web & OS_Nat --> OS_Ver
        end

        %% Layer 3: Client Software
        subgraph Client_Layer ["Lapisan 3: Perangkat Lunak Klien"]
            Browser["Browser: Chrome, Safari, Edge<br/>+ Versi"]
            App["Aplikasi Native / WebView<br/>+ Versi Aplikasi"]

            OS_Ver --> Browser
            OS_Ver --> App
        end

        %% Layer 4: WebAuthn Operation
        subgraph Op_Layer ["Lapisan 4: Operasi WebAuthn"]
            OpType{"Jenis Operasi"}

            Login["Login<br/>(navigator.credentials.get)"]
            Reg["Pendaftaran<br/>(navigator.credentials.create)"]

            Browser & App --> OpType
            OpType --> Login
            OpType --> Reg
        end

        %% Layer 5: Sub-types & Complexity
        subgraph Modality ["Lapisan 5: Modalitas & Kompleksitas"]
            Sub_CUI["CUI / UI Bersyarat"]
            Sub_Auto["Operasi Otomatis"]
            Sub_CDA["CDA / Autentikasi Lintas Perangkat"]

            Login & Reg --> Sub_CUI
            Login & Reg --> Sub_Auto
            Login & Reg --> Sub_CDA
        end
    end

    %% --- BOTTOM: CLASSIFICATION & ACTION (The "What here?" section) ---
    subgraph Analysis ["Analisis Kesalahan & Runtime"]
        direction TB

        %% Classification
        Classification{"Klasifikasi"}

        Exp["Kesalahan yang Diharapkan<br/>(Pengguna Membatalkan Upacara)"]:::expected
        Unexp["Kesalahan Tak Terduga<br/>(Sistem/Crash/Tidak Diketahui)"]:::unexpected

        ClientManifest --> Classification
        Sub_CUI & Sub_Auto & Sub_CDA --> Classification

        Classification --> Exp
        Classification --> Unexp

        %% Detection Logic
        subgraph Detection ["Tujuan Deteksi"]
            P1["P1: Masalah Login"]
            P2["P2: Masalah Pembuatan"]
            Baseline["Deteksi Penyimpangan Baseline<br/>(Peningkatan yang Diharapkan)"]
            NewErr["Deteksi Anomali Baru<br/>(Peningkatan Tak Terduga)"]
        end

        Exp --> Baseline
        Unexp --> NewErr
        Exp & Unexp --> P1 & P2

        %% Actionable Outcomes
        subgraph Action ["Tindakan Mitigasi"]
            Fix["Terapkan Perbaikan Darurat / Versi Baru"]:::action
            Fallback["Aktifkan Fallback Otomatis<br/>(Nonaktifkan Passkey)"]:::action
        end

        P1 & P2 & NewErr --> Fix
        P1 & P2 & NewErr --> Fallback
    end

    %% Connectors
    Infrastructure -.-> Environment
```

Wawasan utamanya: nama `error.name` mentah hanya masuk akal jika Anda mengetahui di
lapisan Lingkungan mana kesalahan itu diproduksi, Operasi mana yang sedang berjalan, dan
apakah kesalahan tersebut Diharapkan atau Tidak Terduga. Bagian di bawah ini membahas apa
yang harus dicatat dan bagaimana menindaklanjutinya.

## 11. Apa yang harus dicatat agar Kesalahan dapat di-debug

Sebagian besar klasifikasi kesalahan dalam artikel ini dapat dilakukan dengan sinyal sisi
klien saja. SDK observabilitas sisi klien menangkap cukup konteks untuk mengklasifikasikan
sebagian besar kesalahan WebAuthn. Ini juga cara arsitektur SDK observabilitas Corbado:
lapisan sisi klien menangani atribusi kesalahan, waktu, konteks operasi, dan deteksi
platform. Pencatatan sisi server menambahkan lapisan kedua untuk kegagalan yang hanya
dapat dilihat oleh backend.

Persyaratan utamanya: setiap upaya harus dapat digabungkan ujung-ke-ujung (end-to-end). ID
korelasi bersama (mis., `auth_flow_id`) menghubungkan konteks sisi klien dengan hasil
verifikasi server.

### 11.1 Sinyal Sisi Klien (SDK Frontend)

| **Sinyal**                                   | **Mengapa itu penting**                                                                                                                                                |
| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `error.name` + kelompok alasan dinormalisasi | Kesalahan browser mentah + klasifikasi Anda                                                                                                                            |
| Jenis operasi                                | UI Bersyarat, login modal, buat manual, buat bersyarat, tambah-otomatis. **CDA (Autentikasi Lintas Perangkat)** adalah kompleksitas tersendiri.                        |
| Konteks Lingkungan Penuh                     | OS + Versi, Browser + Versi, **Merek/Model Perangkat Keras**, **Pengaturan Autentikator** (mis., GPM diaktifkan?)                                                      |
| Autentikator / konteks pengelola kredensial  | Ekstensi dan kerusakan penyedia                                                                                                                                        |
| Waktu menuju kesalahan dari mulai operasi    | Penolakan segera (`<1 dtk`) vs pembatalan pengguna (1-15 dtk) vs waktu habis (30 dtk+)                                                                                 |
| Status Jaringan / Konektivitas               | Kesalahan jaringan seringkali bermanifestasi sebagai kesalahan klien. Lacak jika pengguna sedang offline dan **antrekan log** untuk dikirim ketika konektivitas pulih. |
| Apakah UI QR/hybrid muncul                   | Lokal vs kegagalan lintas-perangkat                                                                                                                                    |
| Id korelasi (`auth_flow_id`)                 | Gabungkan dengan log server                                                                                                                                            |

### 11.2 Sinyal Sisi Server (Verifikasi Backend)

Kegagalan verifikasi server terjadi setelah browser mengembalikan kredensial dan tantangan
yang ditandatangani. Ini harus berupa kesalahan terstruktur dengan kode eksplisit, jangan
dicampur ke dalam keranjang yang sama dengan nama `DOMException` sisi klien. Lihat:
[Implementasi server WebAuthn](https://www.corbado.com/id/blog/implementasi-server-webauthn).

| **Sinyal**                                            | **Mengapa ini penting**                                                                                                                                                                                        |
| ----------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Tantangan tidak cocok / tantangan kedaluwarsa         | Masalah waktu sesi atau putar ulang                                                                                                                                                                            |
| Asal / RP ID tidak cocok                              | Kesalahan konfigurasi multi-domain                                                                                                                                                                             |
| Tanda tangan tidak valid / kredensial tidak ditemukan | Kredensial dihapus atau rusak. Kasus umum: login UI bersyarat dengan kunci sandi yang sudah dihapus pengguna di sisi server. Gunakan Signal API untuk menjaga sinkronisasi daftar kredensial klien dan server. |
| User handle mismatch                                  | Masalah pemetaan akun                                                                                                                                                                                          |
| Correlation id (`auth_flow_id`)                       | Gabungkan dengan konteks sisi klien                                                                                                                                                                            |

Jika Anda menginginkan model alur penuh (penurunan pada setiap langkah dan konversi antar
langkah), lihat: telemetri passkey untuk memahami penurunan.

[Watch on YouTube](https://www.youtube.com/watch?v=wnrXJzvBjsU)

Dengan adanya data ini, kesimpulannya menjadi sederhana: sebagian besar "kesalahan"
menjadi perbaikan UX, perbaikan cakupan, atau perbaikan konfigurasi. Namun, membangun dan
memelihara klasifikasi ini sendiri merupakan pekerjaan berkelanjutan yang signifikan.

## 12. Melampaui Nama Kesalahan: bagaimana Corbado mengubah Kesalahan mentah menjadi Sinyal yang dapat ditindaklanjuti

Daftar periksa log di atas menangkap sinyal mentah. Di produksi pada skala besar,
`error.name` saja tidak cukup. Membangun klasifikasi ini sendiri adalah pekerjaan
berkelanjutan yang signifikan: pesan kesalahan berubah seiring dengan rilis browser dan OS
baru, penyedia
[pengelola kata sandi](https://www.corbado.com/id/blog/pengujian-password-manager-pihak-ketiga-passkey-aplikasi)
mengirimkan pembaruan yang mengubah perilaku upacara dan ciri kesalahan baru muncul dengan
peluncuran fitur baru.

### 12.1 Mengapa `error.name` saja tidak cukup

`NotAllowedError` yang sama dapat berarti enam hal yang berbeda bergantung pada tiga
dimensi yang tidak dipisahkan oleh browser untuk Anda:

| **Dimensi**                 | **Apa yang diberikan browser** | **Apa yang sebenarnya Anda butuhkan**                                                                | **Contoh**                                                                                                                     |
| --------------------------- | ------------------------------ | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Konteks operasi**         | `NotAllowedError`              | Apakah itu UI bersyarat, login modal, pembuatan manual, pembuatan bersyarat, atau lampiran otomatis? | Android mengembalikan "unknown error" yang sama untuk pembatalan masuk (diharapkan) dan kegagalan pembuatan (tidak diharapkan) |
| **Pengaturan waktu**        | Tidak ada data durasi          | Penolakan instan (`<1 dtk`) vs pembatalan pengguna (1-15 dtk) vs batas waktu (30 dtk+)               | 200 md = penolakan lingkungan; 5 dtk = pengguna melihat dialog dan membatalkannya; 35 dtk = batas waktu                        |
| **Platform + autentikator** | `error.name` generik           | OS, browser, versi, pengelola kredensial untuk setiap kesalahan                                      | "pengguna menutup dialog" di Chrome dan "isi otomatis tidak tersedia" di Safari keduanya muncul sebagai `NotAllowedError`      |

### 12.2 Apa yang ditangkap SDK pengamatan Corbado

Ini adalah masalah yang dibangun untuk diselesaikan oleh
[SDK observabilitas Corbado](https://www.corbado.com/pricing). Ini adalah integrasi
antarmuka ringan yang terletak di atas
[implementasi kunci sandi](https://www.corbado.com/id/blog/passkey-day-2-problems) Anda yang sudah ada, bekerja
dengan server WebAuthn mana pun dan IDP apa pun, dan secara otomatis mengklasifikasikan
setiap kesalahan WebAuthn ke dalam ketiga dimensi tersebut:

| **Kemampuan**                        | **Apa yang dilakukannya**                                                                                                                                                                                                                                                                                               |
| ------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Atribusi kesalahan**               | Menangkap OS, versi OS, browser, versi browser dan autentikator pada setiap upaya upacara                                                                                                                                                                                                                               |
| **Mode operasi**                     | Menghubungkan setiap kesalahan dengan operasi spesifik (UI bersyarat, login modal, pembuatan manual, pembuatan bersyarat, penambahan otomatis) sehingga `NotAllowedError` yang sama mengarah ke akar penyebab yang berbeda                                                                                              |
| **Waktu dari awal tindakan**         | Merekam durasi dari permulaan upacara untuk membedakan penolakan segera, pembatalan pengguna dan waktu habis tanpa menerka-nerka                                                                                                                                                                                        |
| **Klasifikasi kesalahan cerdas**     | Mencocokkan dengan seluruh konteks kesalahan (bukan hanya nama), melakukan normalisasi atas ragam **Lingkungan** (OS, Hardware, Pengaturan). Memprioritaskan grup kesalahan berbeda seperti **CDA** vs. Lokal, dan membedakan kesalahan yang **Diharapkan (Pengguna Membatalkan)** dari **Tak Terduga (Sistem Gagal)**. |
| **Fragmentasi pengelola kata sandi** | Mendeteksi saat perpanjangan dari pengelola kredensial (Bitwarden, 1Password, LastPass) mengintersep upacara lantas mereturn jawaban di luar standar, sambil menepis kerusakan akibat platform yang tersirat via ekstensi                                                                                               |

Inilah tingkatan pemantauan (Observe): penampakan ke perkara-perkara internal yang
berkisah soal pengamatannya, tanpa turut mengguncang maupun membuat rombakan struktur pada
tatanan program buatanmu.

### 12.3 Dua Cara untuk men-debug: Top-Down dan Bottom-Up

Konsol manajemen Corbado mendukung dua jalur investigasi:

**Top-down (dasbor ke akar penyebab):**

1. **Pantau untuk dua jenis anomali berbeda:**
    - **Peningkatan Kesalahan yang Diharapkan (Penyimpangan Baseline):** Apakah lingkungan
      tertentu (mis., [iOS 18](https://www.corbado.com/blog/ios-18-passkeys-automatic-passkey-upgrades).2 di
      iPhone 15) mengalami peningkatan bertahap dalam "pembatalan pengguna"? Ini sering
      menunjukkan gesekan UX yang diperkenalkan oleh pembaruan OS.
    - **Peningkatan Kesalahan Tak Terduga (Lonjakan):** Kesalahan yang sama sekali baru
      atau lompatan tiba-tiba kegagalan. Ini biasanya menunjukkan perubahan yang merusak
      (pembaruan tumpukan IDP internal) atau regresi dalam versi browser baru.
2. **Prioritaskan menurut dampak:**
    - **P1: Masalah Login.** Jika tingkat keberhasilan login menurun, segera waspada.
    - **P2: Masalah Pembuatan.** Pantau tren, tetapi hindari membangunkan teknisi untuk
      lonjakan "pembatalan pengguna" dalam alur pembuatan.
3. **Selidiki Lingkungan:** Gunakan dimensi yang lebih rinci (Hardware, Auth Settings)
   untuk mengisolasi apakah masalah tersebut bersifat global atau spesifik untuk
   "perangkat [Samsung](https://www.corbado.com/blog/samsung-passkeys) dengan Android 14".
4. **Mitigasi:** Jika lonjakan kritis terdeteksi, siapkan **Kill Switch**. Secara otomatis
   atau manual nonaktifkan kunci sandi untuk lingkungan spesifik itu dan kembali ke
   OTP/[Kata sandi](https://www.corbado.com/id/blog/cara-mengaktifkan-passkey-android) untuk menjaga tingkat
   login saat Anda menyelidiki.

**Bottom-up (pola kesalahan ke dampak):**

1. Mulai dari tampilan klasifikasi kesalahan. Tinjau pola kesalahan yang diklasifikasikan
   dan volumenya.
2. Perbaiki pemetaan kesalahan saat pola baru muncul (mis. versi browser baru yang merilis
   pesan kesalahan yang berbeda).
3. Kesalahan berkorelasi silang dengan perubahan KPI dan dimunculkan sebagai anotasi di
   dasbor, sehingga lonjakan dalam pola kesalahan tertentu secara otomatis ditautkan ke
   metrik yang dipengaruhinya.

Kedua jalur menyatu: top-down memberi tahu Anda ada sesuatu yang salah, bottom-up memberi
tahu Anda alasannya. [Asisten Analitik AI](https://www.corbado.com/ai-analytics-assistant) menghubungkan keduanya
dengan memungkinkan Anda mengajukan pertanyaan dalam bahasa alami di seluruh data
kesalahan dan metrik adopsi.

Tim yang ingin menindaklanjuti sinyal ini dapat beralih ke **Adopt**, yang menambahkan
[intelijen passkey](https://docs.corbado.com/corbado-connect/features/passkey-intelligence)
untuk secara otomatis membatasi upacara, mengoptimalkan prompt pendaftaran dan
menyembuhkan status passkey yang rusak. Untuk lingkungan yang diatur atau penyebaran skala
besar (hyperscale), **Enterprise** menambahkan hosting penyewa tunggal, integrasi SIEM dan
konfigurasi yang mematuhi [PSD2](https://www.corbado.com/blog/psd2-passkeys).

## 13. Kesimpulan

Nama kesalahan WebAuthn bukan sebuah vonis. Itu adalah petunjuk - dan itu hanya dapat
ditindaklanjuti saat Anda menghubungkannya ke jenis operasi, waktu, dan konteks platform.

- **Apa arti nama kesalahan WebAuthn yang paling umum di produksi?** Sebagian besar
  memetakan ke sekumpulan kecil lapisan: aliran kontrol pengguna (`NotAllowedError`),
  siklus hidup/konkurensi aplikasi (`AbortError`), konteks/konfigurasi keamanan
  (`SecurityError`), atau bug opsi/status (`InvalidStateError`, `ConstraintError`,
  `DataError`). Sebagian besar volume adalah `NotAllowedError`, dan sebagian besar dari
  itu adalah perilaku yang diharapkan (pengguna menutup prompt).
- **Bagaimana Anda membedakan `NotAllowedError`?** Gunakan waktu (penolakan instan vs
  pembatalan pengguna vs batas waktu), indikator QR/hibrida (ketidaksesuaian
  ketersediaan), konteks aktivasi pengguna (terutama di iOS/Safari) dan jenis operasi (UI
  bersyarat vs login modal vs [pembuatan passkey](https://www.corbado.com/id/faq/bagaimana-passkey-dibuat) vs
  pembuatan bersyarat). Jangan memperlakukan semua `NotAllowedError` sebagai satu mode
  kegagalan.
- **Mengapa jenis operasi penting?** `error.name` yang sama selama login UI bersyarat
  adalah sinyal yang sama sekali berbeda dari pada saat pembuatan bersyarat atau
  [pembuatan passkey](https://www.corbado.com/id/faq/bagaimana-passkey-dibuat) manual (pengguna menutup dialog).
  Mencatat jenis operasi beserta kesalahannya adalah hal yang mengubah `NotAllowedError`
  umum menjadi kelompok yang dapat ditindaklanjuti.
- **Konteks minimum apa yang membuat kesalahan dapat di-debug?** Tangkap `error.name`,
  jenis operasi, waktu terjadinya kesalahan dari awal operasi, tipe alur, apakah UI
  QR/hibrida ditampilkan, OS/browser/perangkat (termasuk versi), id korelasi
  (`auth_flow_id`) dan penolakan verifikasi server sebagai kode eksplisit.

Dua aturan praktis yang berlaku untuk semua jenis kesalahan: jangan pernah menunjukkan
kesalahan peramban mentah kepada pengguna - selalu berikan alur alternatif yang jelas -
dan pisahkan percobaan lokal dari percobaan QR/hibrida lintas perangkat, karena mereka
gagal karena alasan yang berbeda dan memerlukan perbaikan yang berbeda. Pada skala besar,
memelihara klasifikasi kesalahan di seluruh peramban, versi OS, dan pengelola kredensial
adalah pekerjaan yang berkelanjutan. Pertimbangkan untuk menggunakan SDK observabilitas
dengan pustaka pola yang dipelihara daripada membangunnya dari awal.

## Pertanyaan yang Sering Diajukan

### Bagaimana cara membedakan antara pengguna yang membatalkan permintaan kunci sandi dan perangkat yang tidak memiliki kunci sandi?

Di web, peramban menyatukan kedua kasus tersebut menjadi `NotAllowedError` demi alasan
privasi, jadi Anda tidak dapat membedakannya secara langsung. Gunakan waktu sebagai
proksi: kesalahan di bawah 1 detik biasanya berarti penolakan lingkungan atau hilangnya
kemampuan, sedangkan 1-15 detik menunjukkan bahwa pengguna melihat dan mengabaikan dialog.
Di aplikasi asli iOS dan Android, pengaturan `preferImmediatelyAvailableCredentials`
sebelum permintaan memberi Anda sinyal "tidak ada kredensial" yang jelas (iOS kode 1005,
Android `GetCredentialRequest`) sebelum UI apa pun ditampilkan.

### Mengapa tingkat kesalahan WebAuthn saya sangat tinggi meskipun kunci sandi tampaknya berfungsi bagi sebagian besar pengguna?

Dalam pengerahan kunci sandi skala besar yang dioptimalkan, lebih dari 95% kesalahan
WebAuthn yang tercatat adalah pembatalan pengguna yang wajar, bukan kegagalan sistem.
Melacak jumlah `error.name` mentah tanpa memisahkan "pengguna menutup prompt" dari
kegagalan sungguhan akan melambungkan metrik kesalahan dan menutupi kemunduran
sesungguhnya yang tersembunyi di dalam banyaknya `NotAllowedError`. Pisahkan perhitungan
Anda berdasarkan jenis operasi dan perlakukan keranjang yang dibatalkan oleh pengguna
terpisah dari kesalahan yang tak terduga seperti `SecurityError`, `ConstraintError` serta
`DataError`.

### Apa maksud dari kode ASAuthorizationError 1005 di iOS dan bagaimana sebaiknya saya menggunakannya?

Kode iOS 1005 (`NotInteractive`) berarti
[tidak ada kunci sandi yang tersedia](https://www.corbado.com/id/blog/pemecahan-masalah-passkey-solusi) pada
perangkat saat `preferImmediatelyAvailableCredentials` diatur pada
`ASAuthorizationController`, dan tak satu pun UI ditampilkan kepada pengguna. Ini
merupakan tanda bersih bahwa "kunci sandi tak terdeteksi keberadaannya di perangkat ini",
sesuatu yang browser web gagal berikan karena hambatan privasi. Biasakan
mengklasifikasikannya berdasarkan kode numerik, bukan pada `localizedDescription`, sebab
seluruh rangkaian pesan dari
[Apple](https://www.corbado.com/id/blog/cara-menghapus-kunci-sandi-apple-windows-android) diterjemahkan ke tak
kurang dari 30 bahasa dan tak jarang mengalami perombakan antar rilis OS.

### Bagaimana sebaiknya saya menangani NotAllowedError selama pembuatan bersyarat atau alur tambah passkey yang dipicu otomatis?

Selama pembuatan bersyarat, `NotAllowedError`, `AbortError` dan `InvalidStateError`
merupakan hasil yang diharapkan dan harus diabaikan tanpa menimbulkan gangguan, alih-alih
diperlihatkan sebagai ralat. `NotAllowedError` menandakan bahwa fitur isi otomatis
(autofill) tak tersedia atau tab halaman telah ditinggalkan, sementara `InvalidStateError`
memberitahukan bahwasanya kunci sandi telah tersedia di penyedia. Sebelum memanggil fungsi
tersebut, pakailah `getClientCapabilities()` dalam memastikan kompatibilitas
`conditionalCreate` dan pantau visibilitas dokumen di halaman demi mencegah
penggelembungan hitungan galat (error) Anda.

### Konteks apa yang harus saya sertakan bersamaan dengan error.name supaya kegagalan WebAuthn bisa benar-benar di-debug?

Catat jenis operasional (UI bersyarat, log masuk berbasis modal, pembuatan cara usang,
atau penciptaan bersyarat beserta perlekatan otomatisnya), waktu sejak mulai terpicu
sampai ralat mengemuka, tipe OS, rupa sistem perambah (browser), varian perangkat
(mesinnya), keterlihatan bentuk UI-nya, berikut rujukan keterkaitan (correlation ID)
penyambung notifikasi ralat dari pangkalan datanya. Penolakan dari pihak belakang penyaji
(seperti selisih angka kode dan tak samanya rujukan nama log, plus ketiadaan kata-kuncinya
di brankas) wajib tertuang melalui susunan struktur dengan baik, tanpa dicampur dengan
kumpulan galat yang datangnya dari pihak gawai `DOMException`. Elemen-elemen itu jika
dihimpun mampu mengarahkan hampir semua tipe kepalsuan hingga tertampung rapi dalam
ember-ember solusinya, bukan cuma diterka-terka acak.
