Skip to main content
Every rejection from this library is an NfcError carrying a code. That is the whole point of the type: a code can be branched on, and a message cannot.
NfcError.is brands on the error’s name, not on instanceof, so it still works when two copies of the package end up in one bundle — which happens, and which breaks instanceof in a way that is very hard to see. Always prefer it.
Every error also carries these:
NfcErrorCode
The stable, branchable identifier. Every code on this page is one.
string | undefined
What the platform supplied, when it supplied anything — NFCReaderError:201, android.nfc.TagLostException. Worth logging; worth putting in a bug report.
NfcPlatform
ios, android or web.
unknown
The original throw, where there was one.
boolean
Whether moving the tag away and back is worth trying.

The four you should always handle

Everything else is a bug, a tag problem, or a configuration problem. These four are ordinary life:

Session lifecycle

Hardware, permissions and configuration

Tags

Exchanges

NDEF

Card emulation

Programming errors

These mean the call was wrong, not that NFC failed. They should never reach a user.

Two distinctions worth internalising

aborted is not userCancelled

The first is your AbortSignal; the second is the user dismissing the sheet. The library being replaced collapsed a user cancellation into “closed with no error”, so the two could not be told apart — and an app cannot decide whether to show a message without knowing which happened.

timeout is not sessionTimeout

The first is the deadline you set; the second is iOS’s 60-second cap on a reader session, which no library can extend. The remedy differs: raise your own, or split the work.

Next

Sessions

Where most of these codes come from, and the options that avoid them.

Setup

Where entitlementMissing, hceUnsupported and techUnavailable get fixed.