A write replaces; it does not merge
ChannelBuddy does not send the radio a list of your changes. It sends the whole codeplug, block by block, and the radio erases the codeplug region as it commits, keeping only the blocks that arrived in that session. Anything not sent is not left alone. It is gone.
That is not a design preference, it is the radio's behaviour, and an early version of this app that skipped "unchanged" blocks wiped most of a codeplug: channels gone, menu language reset, a power-on password nobody had set. After a write the radio holds exactly the image ChannelBuddy sent, and nothing else. Not your old codeplug with your edits laid on top.
Two things sit outside that image on purpose. The factory block — serial number, band-plan byte — is refused block by block, so a codeplug write can never move your band plan. And the digital contact database is left alone unless you tick it, in which case it goes in a second session after the codeplug is committed.
On the AT-D878UVII, AT-D578UVII and AT-D168UV a full write takes several minutes, and the dialog explains why: it is the speed of that radio's USB interface, not the size of the image. The AT-D890UV sends the same full image and writes at close to factory-CPS speed.
What actually reaches the radio
Your edits reach the radio, including the parts that feel peripheral. General settings, the DTMF, 2-Tone and 5-Tone tables, FM broadcast presets, roaming and the encryption key tables are all encoded into the write image on the shipped models.
There are known exceptions, and they are per-model. The AM air-band list is carried by the direct write on the D890UV only. Where a section is not carried, your edits still round-trip into the downloaded .rdt, so the factory CPS can put them on the radio. Each tab in the editor states which of the two applies to your radio, from a per-model list kept beside the build code. Trust the tab rather than a memory of this page: the exceptions here shrink as encoders land, and this page is the slower of the two to notice.
What the backup is for is everything ChannelBuddy does not model at all. Read one, and the server builds your write on top of the radio's own bytes, so those regions ride through untouched. Skip it and the write carries ChannelBuddy's modelled image alone; the dialog warns that you have no restore point and that some settings may reset. On the D168UV and D578UVII the backup is not optional: the write image is your backup with your edits overlaid, and preparing without one fails outright.
The safety floor
Writing a codeplug cannot brick your radio. The app says so in its beta notice — There is no risk of bricking your radio — and the code backs it up: a codeplug write goes into codeplug addresses and nothing else, and refuses the factory block outright. Firmware flashing is a separate tool behind an admin login that this dialog cannot reach. The worst realistic outcome is a codeplug you have to put back — a bad evening, not a dead radio.
Backups are your only undo
There is no version history for what is on the radio. Once a write commits, whatever was in that flash is gone, and the backup the write flow offers is the only copy of it you control.
What the backup holds
A byte-level read of the radio's codeplug memory: every region ChannelBuddy can write, plus a good deal it does not model, sized from real captures of the factory CPS. The dialog estimates about a minute; a larger radio map takes longer. It does not include the bulk DMR contact database, firmware or calibration. Your browser saves it as anytone_backup_ plus a timestamp, and the dialog leaves a Save backup.json link in case the download was blocked. Treat it as sensitive: it is a raw image, so any AES or ARC4 keys in your codeplug are in it in the clear.
One thing the app does not do for you: nothing checks that the backup covered every block the write needs. Blocks it missed are written from ChannelBuddy's own image anyway, and you are not told. In the normal flow that is safe, because the backup can only have come from the radio you are connected to in this same session — but it does mean a short read passes quietly rather than being caught.
The server keeps its own copy of the backup you posted, but only for the life of the write: discarded when the write reports success, held for a day or archived for investigation when it fails. That is not an archive you can retrieve. Keep your own file.
Restoring from a backup
A Restore from backup button appears in the write dialog's footer when the codeplug write fails, or when the read-back verify fails, and only if a backup was read in that session. It reconnects, writes the backup's own bytes back and commits — a true restore, not a re-import. It is deliberately absent in the two cases where the codeplug is committed and intact: a failed digital-contact phase, and a verify that could not run.
No control in ChannelBuddy uploads a saved anytone_backup_….json back to a radio; the Projects page accepts .rdt files only. The one-click restore exists just while the write dialog still holds the backup it read. Keep the file anyway — it is the only byte-level copy of your radio, and it is what support would work from.
If you have already closed the dialog, go the other way: read the radio again from the Projects page (Read from radio, then Import as project) to see what it holds now, and write back a project you trust.
If a write stops partway
The write is committed by a single command at the end of the session. Everything before it is preparation; everything after it is on the radio. Where you stopped decides what you are looking at.
| Stage | State of the radio | What to do |
|---|---|---|
Connecting — Entering PC mode… | Untouched. Model and band plan are read. | Close freely. |
Reading full radio backup… | Untouched; this stage only reads. | Close or retry; a read aborts cleanly. |
Preparing write data on the server… | Untouched; the work is on the server. | Stuck at Queued… is a server problem, not the radio. |
Writing codeplug… | Blocks in flight, not yet committed. On an error the app tears the session down, which sends the commit if the link is still alive. So the radio may hold a part-written image with the rest of the region erased, or the old codeplug untouched. | Treat it as unknown; the message says the codeplug may be partial. Restore, or write again. |
Committing codeplug… | Where it becomes real. The radio reboots. | Let it finish; the app waits about thirty seconds and re-acquires the port itself. |
Writing digital contacts… | The codeplug is committed and intact; this second session touches only the contact area. | Codeplug written OK, but the digital-contact write failed means exactly that. Re-run the write. |
Verifying codeplug (reading back)… | Committed; the app is re-reading it and comparing byte for byte. | A verify that cannot run is not a failure: power-cycle and read back. A verify that fails means the radio's bytes differ from what was sent — restore, or write again. |
While the codeplug is being written, leave the tab open and the cable in. The dialog refuses to close during a write on purpose. If something looks wrong, let it fail on its own and use the restore.
A pulled cable does not announce itself. The app does not listen for the browser's disconnect event, so an unplug surfaces later as a timeout that looks like any other write error — and you cannot tell a lost link from a part-written commit by looking at the radio. Treat every interrupted write the same way, and verify or rewrite it before you trust it on the air.
Why a write gets refused
Checks on the codeplug
When the dialog opens, the server validates the project and lists what blocks it under Fix these before writing to the radio:. The same checks run again when you prepare. The ones people hit:
Add at least one zone before writing to the radio— a zoneless codeplug is rejected, as it is by the factory CPS.Add at least one radio ID before writing to the radio— an empty Radio ID list is refused even for analog-only use.- Digital channels with no Radio ID, or one the project does not define. Every
D-DigitalandD+A TX Dchannel needs one to transmit. Add at least one channel before building a codeplug— VFO A and B do not count.- Blank or non-numeric frequencies, an over-long scan list, out-of-range scan timers.
Warnings do not block, but read them: an empty zone, or a channel naming a talk group that is not in the table, describes a radio that will surprise you.
Checks against the radio in front of you
- Wrong model. The radio's reported model must match the project's. Every name a model answers to is accepted, rebadges included; anything else fails closed.
- Band-plan mismatch. The radio accepts only channels inside its own band plan, so a mismatched write would drop the out-of-plan ones silently. The app refuses and points at
Change Radio Bandplanon the Settings tab. Move the radio, reconnect, then write.
A write can also be refused because you have used your plan's radio writes for the day, a counter that resets at midnight UTC. /about covers what a plan allows.
Writing someone else's codeplug
A shared or public codeplug can go straight to your own radio without cloning it, and the dialog then asks for your DMR ID and callsign before it will prepare anything.
The reason is on-air, not administrative. A codeplug carries its author's identity: their DMR ID in the first radio-ID record, their callsign in the APRS settings. Write it unchanged and your radio transmits as them, every call and beacon logged against another operator's licence. So the server stamps your own DMR ID and callsign into both as it builds the write, and refuses a viewer's write that does not carry them. The shared project itself is untouched. On models whose write path cannot yet stamp an identity, shared codeplugs stay owner-only, and the page says so where the write button would be.
Browser and cable
Talking to a radio needs a browser with Web Serial, a USB cable, and the radio powered on and in PC mode before you connect; /about lists which browsers qualify, and When it goes wrong sorts the failures by kind.