Skip to main content...

ReallyOpenGD77 WebCPSd Troubleshooting

Connection Issues

“WebUSB requires Chrome/Edge/Brave”
This is a browser limitation, not a bug in this app. WebUSB is only implemented in Chromium-based browsers. Firefox 151 added the Web Serial API, but that’s a different API from WebUSB – it doesn’t change this. Safari doesn’t implement either. Every other CPS feature (editing, CSV/JSON, DMR ID search, etc.) works fine in any browser; only the physical radio connection needs Chrome, Edge, or Brave.
Radio doesn’t show up in the browser’s USB device picker

On Linux, the kernel’s cdc_acm driver (and sometimes brltty, if installed) grabs the radio’s USB serial port before the browser ever gets a chance at it, and /dev/bus/usb/* isn’t writable by regular users by default. Run the one-time setup script on the machine whose browser you’re using (not a remote server, if you’re self-hosting on one):

curl -fsSL https://webcps.app/webusb | sudo bash

See the Linux WebUSB Setup Guide for details, and unplug/replug the radio after running it.

Windows and macOS don’t need any of this – if the radio still doesn’t appear there, double-check the cable (some are charge-only) and that you’re using a Chromium-based browser.

Connect button does nothing / no device picker appears when accessing from another device

Browsers only expose WebUSB in a secure context: https://, or http://localhost specifically. If you’re self-hosting on a Pi/server and opening the CPS from a browser on a different device, a plain http://<its-ip>:4938 URL will never have WebUSB available – no error message, the picker just silently won’t work. This is a browser security policy, not something this app can work around from the server side.

See Do You Even Need HTTPS? in the Deployment Guide – every deployment path (Docker, Pi, Proxmox) has a one-command Caddy setup for this, with either a real certificate or a self-signed one for LAN-only use.

start.sh fails with “Address already in use”

Something is already listening on port 4938 – most likely a previous run of this app that’s still alive. Find and stop it:

lsof -i :4938
kill <PID>

Then run ./start.sh again. If you intended to run two instances, edit the uvicorn command’s --port in start.sh (or your systemd/Docker/Proxmox config) to use a different port.

Read / Write Issues

Read/Write fails with a timeout, or “Not fully connected to radio endpoints”

Try the Reset USB button first – it performs a full USB bus reset in software (USBDevice.reset()), then redoes the CDC line handshake and re-identifies the radio, all without needing to physically unplug anything. This recovers the exact situation a stuck/timed-out transfer leaves the radio in: OpenGD77 firmware won’t answer any further request once a transfer is left unanswered (a page reload mid-read, a dropped USB event, a timeout), and a software bus reset clears that the same way a physical unplug/replug would.

If Reset USB itself fails, a physical unplug/replug is the fallback – the error message says so directly.

Note
“Radio disconnected – please reconnect” is the app noticing the browser’s own USB disconnect event (unplugged, OS reclaimed the device, etc.) – reconnect via the Connect button, no page reload needed.
Backup/Restore refuses with a “wrong bytes to the wrong flash addresses” error
This is an intentional safety check, not a bug. Every backup file is tagged with the radio family it came from (MK22 vs. STM32 – the two chipset families have different flash/EEPROM memory maps). If you try to restore a backup taken from one family onto a radio from the other, the app refuses rather than writing data at the wrong addresses. A closely related check refuses a restore if the backup’s memory layout doesn’t match what the currently-connected app version expects for that radio (e.g. the backup is from a meaningfully older/newer app version). Use a backup taken from the same radio family, with a compatible app version, or start from a fresh read instead.

Data & Caching Behavior (Not Bugs)

BrandMeister repeater list looks out of date
The backend caches the BrandMeister repeater list for 24 hours (BrandMeister is strict about call volume, and the list doesn’t change minute-to-minute). If a live refresh ever fails, the app serves the last-known cache rather than an error – so “slightly stale” is the intended worst case, not a failure. See Technical Specifications for the exact logic.
DMR ID search/import returns nothing right after starting the server
On startup, the backend downloads and parses RadioID.net’s full ~309,000-row database in the background before it’s searchable – this normally takes a few seconds, but can take longer on a slow connection (Raspberry Pi on a weak network, etc.). Check /api/dmrid/status (or just wait a few seconds and retry) before assuming something’s broken.
“TLE fetch failed” when loading satellite data
This is a live, on-demand call to CelesTrak – if it fails, CelesTrak itself is very likely temporarily unreachable or rate-limiting, not this app. Wait a bit and retry. The curated default transponder metadata (frequencies, modes) still works offline; only the live orbital elements need CelesTrak to be reachable.

General Support (Note: lack thereof)

Q: “It’s not working, can you help me?”
A: No.
Q: “But I read the docs and it still doesn’t work!”

A: Read them again. Slower this time.

This project is a labor of love, built and given away for free, not a paid support contract. I’ve tried to make the Deployment Guide, Linux WebUSB Setup, and this page cover the real, recurring issues – if you’ve found and fixed something genuinely new, a pull request is welcome. Issue/bug reports are not accepted (disabled on the repo itself) – if it’s broken, the fix is a PR, not a ticket. A “please fix my setup for me” message is not welcome either way.

Q: “Will you add support for my radio?”
A: Maybe. If it shares a chipset with an already-supported radio (see Supported Radios), just try it – it’ll probably already work, no changes needed. If it’s a genuinely different chipset, that means reverse-engineering a new memory map from scratch, which realistically means permanently donating the radio – reverse-engineering isn’t a borrow-it-for-a-weekend job, and there’s no support workflow here to coordinate shipping it back and forth. See Contributing for how to submit the resulting work as a pull request.
Q: “Can I use this with the manufacturer’s stock (non-OpenGD77) firmware?”
A: No. This talks to OpenGD77 firmware’s specific USB CPS protocol. Stock manufacturer firmware doesn’t implement it and needs the vendor’s own (usually closed-source, Windows-only) CPS instead. Flash OpenGD77 first.
Warning

If you haven't gotten the hint yet: I do not offer support, nor do I respond to support requests. That means do not ask for support.

This exists because closed-source, cloud-dependent CPS tools for OpenGD77 radios annoyed me enough to write a better one, and I'm giving it away for free. That doesn't obligate me to also staff a help desk for it.

Pull requests are always welcome -- see Contributing. Issue/bug reports are not accepted (disabled on the repo itself); if something's broken, the fix is a PR. "Please configure my radio for me" requests will be ignored either way.

Last Revision: 2026-07-12 -- Document Version: 9d18b05
Permanent Link: <https://w0chp.radio/ogd77-webcpsd/troubleshooting/>