> ## Documentation Index
> Fetch the complete documentation index at: https://docs.endstate.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Troubleshooting

> The reader issues operators actually hit - permission prompts, per-origin NFC behavior, and expected console noise.

## The device picker never opens

`connect()`/`start()` must run inside a user gesture (a click handler);
browsers block device prompts otherwise.

## The device picker opens every time

It should not: after the first pairing, `connect()` reconnects through the
browser's stored grant with no prompt. If the picker keeps appearing, check
these, in order.

* **Are you calling `requestDevice()` on every connect?** It always opens the
  chooser, by design. Use it only for pairing - see
  [Connecting once, not every time](/sdks/reader/platforms#connecting-once-not-every-time).
* **Grants are per top-level origin.** `localhost:3000`, a preview URL, and
  your production domain are separate stores, so operators pair once per
  environment.
* **Private/incognito windows never persist a grant.**
* **Some USB-serial readers report no serial number.** Chrome can only store a
  grant permanently for a device it can identify stably; for the rest the
  grant lives in memory and is dropped when the reader is unplugged or the
  browser restarts. Refresh and in-page navigation are still prompt-free.
* **A kiosk that must never prompt** needs the Chrome enterprise policy
  `SerialAllowUsbDevicesForUrls`. That is an IT deployment step, not
  something a page can do.

## The reader is held by another tab or application

Serial devices are exclusive. If a second tab, an encoder utility, or a
terminal session already holds the reader, opening it fails and the
connection state becomes `error` rather than `authorization-required` -
re-pairing will not help. Close the other holder, or call `disconnect()` in
the tab that no longer needs it.

## Phone NFC permission is per-origin

Moving your operator flow to a new domain prompts every operator again, and a
denied permission never re-prompts on its own - it must be re-enabled from the
address-bar lock icon → Permissions → NFC. Screen overlays from other apps
also block the prompt. The SDK surfaces both states through `onError` with
operator-actionable instructions.

## "Serial blocklist" lines in the browser console

When the device picker opens, Chrome logs one line per nearby Bluetooth device
it excludes (for example, wireless headphones). That output comes from the
browser itself - it is expected and harmless.

## Still stuck?

The package ships an `AGENTS.md` for AI coding agents, and these docs are
agent-readable - see [Use Endstate with AI tools](/ai-tools) for the fastest
ways to debug an integration with your tooling.
