Common Web Serial and @gurezo/web-serial-rxjs problems, with check steps and fixes. Start with Quick Start requirements if you have not connected yet. For error code tables, see API concepts and design notes.
Symptoms: Clicking Connect does nothing, or the browser dialog opens but your device is not listed.
Check:
connect$() from a user gesture (button click). The browser blocks the picker otherwise — see Quick Start – Requirements.Fix: Wire Connect to a click handler, fix secure context / browser support, free the port, then call connect$() again and subscribe.
Symptoms: state$ stays at unsupported, or connect$ fails with SerialErrorCode.BROWSER_NOT_SUPPORTED.
Check:
import { isWebSerialSupported } from '@gurezo/web-serial-rxjs';
if (!isWebSerialSupported()) {
console.error('Web Serial API is not available in this browser');
}
Fix: Use an officially supported desktop browser with Web Serial (Chrome 89+, Edge 89+, Opera 75+, Firefox 151+). Safari does not currently implement the Web Serial API. Mobile browsers are untested and out of official support — many also lack the API (so isWebSerialSupported() is false). See Browser support and support policy, the Examples requirements, and the repository README.
Symptoms: navigator.serial is missing, or Examples show an insecure-context message.
Check: The origin must be HTTPS or http://localhost / http://127.0.0.1. Plain http:// on a LAN IP or hostname will not expose Web Serial.
Fix: Serve over HTTPS, use localhost for local development, or tunnel with a tool that terminates TLS. Details: Quick Start – Requirements.
Symptoms: Nothing happens after calling connect$(), send$(), disconnect$(), or dispose$() — no dialog, no send, no teardown.
Check: These methods return cold Observables. They only run when you subscribe.
// Does nothing until subscribed
session.connect$();
// Runs the connection flow
session.connect$().subscribe({
error: (e) => console.error(e),
});
Fix: Always subscribe (or use an operator that subscribes, such as converting to a Promise carefully). The same rule applies to send$, disconnect$, and dispose$. See Quick Start.
Symptoms: Sends appear ignored, replies never arrive on lines$, or the terminal looks broken.
Check:
\r\n on send. Prefer session.send$(${line}\r\n) or a small sendLine helper — see Advanced Usage – Send line.lines$ for newline-delimited logs/parsers. Prefer receive$ (or terminalText$) for terminal-style \r redraw.Fix: Align send endings with the device, and pick lines$ vs receive$ for the consumer. Recipes: Advanced Usage – Line framing.
Symptoms: Picker shows the device but open fails, or PORT_OPEN_FAILED / related errors appear on errors$.
Check: Another process or browser tab may hold the port. Only one opener can own a serial port at a time on most OSes.
Fix: Close other serial tools and tabs, unplug/replug if needed, then connect again from a user gesture. Inspect errors$ — see Inspecting SerialError.
Symptoms: After disconnect or an error, Connect does nothing useful, or you get SESSION_DISPOSED / PORT_ALREADY_OPEN.
Check:
disconnect$, the same session is reusable from 'idle' (or recovered from 'error'). Subscribe to disconnect$, wait for idle on state$, then connect$() again.dispose$, the session is permanent. Create a new createSerialSession() — do not reuse the disposed instance.connect$ while already 'connecting' or 'connected' (PORT_ALREADY_OPEN).Fix: Drive UI from state$. For baud-rate changes or full teardown, dispose$ then create a new session. See Quick Start – Disconnect / Dispose and Advanced Usage – recovery.
Symptoms: Failures are hard to classify from Error.message alone.
Check: Subscribe to errors$ and narrow with error.is(SerialErrorCode.*). For cause-bearing codes, read error.context.cause.
import { SerialErrorCode } from '@gurezo/web-serial-rxjs';
session.errors$.subscribe((error) => {
if (error.is(SerialErrorCode.OPERATION_CANCELLED)) {
console.info('User cancelled the port picker');
return;
}
if (error.is(SerialErrorCode.READ_FAILED)) {
console.error('Read failed:', error.context.cause);
return;
}
console.error(error.code, error.message, error.context);
});
Also handle error on connect$().subscribe({ error }) and send$().subscribe({ error }) — the same SerialError is multiplexed on errors$.
Fix: Branch on codes; full tables live in SerialError / SerialErrorCode.
If you still cannot resolve the issue, open a GitHub Discussion for usage questions, or a bug report via the English / Japanese issue forms.
Please include:
@gurezo/web-serial-rxjs and rxjs versionsSerialSessionStatus / SerialErrorCode (and context if present)