Skip to content

Known Bugs

Active issues + workarounds. Maintained by hand; reported bugs land in the bugs@funkwelt.net inbox.

Active

  • Clicking a spot right after an ATU tune can wedge CAT (Yaesu). The self-healing from 1.17.4/1.17.5 works reliably as long as no spots are clicked right after tuning — but a click into the still-sluggish rig can wedge the CAT chain badly enough that even the auto-reconnect takes long or fails. Workaround: wait ~15 seconds after tuning (until the CAT badge has healed itself once), then click spots. A structural fix (QSY queue) is designed and will ship once it can be tested on our own hardware.
  • Contest scoring (new in v1.10.0) is still being road-tested. The completely rebuilt scoring engine has not yet been cross-checked against official result lists for every contest — verify final scores before submitting. ARRL RTTY Roundup, Russian DX, All Asian DX and JIDX now have their own rule sets (built against the official regulations), but no comparison log exists yet. For the IARU HF scoring ("same ITU zone") your own CQ/ITU zone must be set in the station settings.

Fixed in v1.24.1

  • DX cluster tab stuttered on incoming spots (CPU bursts up to 77 %, "layout storm"). Caused by rebuilding the table columns + re-filtering on every render. Fixed by caching the filtered spot list / spotter evidence and a differential table reload (only on an actual row change).
  • High CPU load with CAT active (~60 %): the logbook (QSO entry, solar panel, content tree) re-rendered on every S-meter tick of the rig. Now down to ~23 % — only the radio panel still reacts live to the transceiver values.

Fixed in v1.24.0

  • Pure feature release (LLOTA — Lakes and Lagoons On The Air, the fifth outdoor program — see changelog). No bug fixes.

Fixed in v1.23.0

  • Pure feature release (send eQSL cards by mail — see changelog). No bug fixes.
  • Also: the English translation was completed (eQSL texts plus propagation/split strings from 1.21/1.22 that still showed in German in the English UI).

Fixed in v1.22.1

  • A normal spot click switched the active VFO (Icom rigs with two VFOs) (reported by HB9HJI, IC-7610): since the split-from-spot feature (1.22.0) HAM-Tools sent a split-off command to the rig on every spot click — even for a plain spot with no split hint. On Icom rigs with two VFOs (e.g. IC-7610) this switched the active VFO to B even though the frequency was set correctly on VFO A. The split-off command is now only sent when split was actually active before.

Fixed in v1.22.0

  • IC-705 WLAN: the last entered credentials could get lost (found in-house): the radio IP, user and password of the direct WLAN connection were tied to the active CAT configuration and could disappear on a config switch or app restart. They are now stored app-wide.
  • IC-705 WLAN: reconnecting often required a TRX power cycle (found in-house): on quit HAM-Tools did not log off cleanly, the IC-705 kept its single network session, and reconnecting failed until the rig was power-cycled. Now: clean log-off on quit + automatic reconnect retry that keeps trying until the radio releases the session.
  • Otherwise a feature release (split from the spot comment — see changelog).

Fixed in v1.21.0

  • Pure feature release (propagation intelligence: grayline world map, "Prop" traffic light per spot, "Open now" matrix and the world map in the logbook cluster — see changelog). No bug fixes.

Fixed in v1.20.1

  • Moving columns could wreck the tables (found in-house, BUG-20260607-1706-TJ): on macOS 26, dragging a column in the spot tables (DX cluster, POTA, SOTA, WWFF, BOTA) or the QSO table led to scrambled cell contents, phantom columns, a frozen UI or — with a column arrangement saved by an older version — a crash. Root cause is an Apple bug in SwiftUI's table code; all six tables now run on a native NSTableView foundation. One-time side effect: the column order resets to the default after the update (visibility is preserved).

Fixed in v1.20.0

  • POTA: "already logged" was not visible per station (reported by HB9HJL): the ATNO filter works per park, the cluster ATNO status per country — whether the specific station was already in the log was not shown anywhere. Now: green ✓ marker per activator call (24h, with band tooltip) + "Hide logged" filter.
  • Otherwise a pure feature release (distance displays, continent multi-select, worked-B4 filter — see changelog).

Fixed in v1.19.1

  • TX power was stuck at 100 W and never tracked (reported by HB9HJL, thanks!): the power field in the QSO form now automatically follows the TRX power read via CAT, in actual watts; QSOs logged via WSJT-X/N1MM carry the logger's power, falling back to the CAT power.
  • Orphaned rigctld processes could block CAT startup: with several HAM-Tools installations around (e.g. release app + test build), their rigctld background processes survived force-quits, held the CAT port and caused "CAT err". CAT start now cleans up all HAM-Tools-owned rigctld leftovers (externally started rigctld instances are left alone).

Fixed in v1.19.0

  • Auto-lookup wrongly required QRZ credentials: Users with only HamQTH configured got no automatic callbook lookup on tabbing out of the call field or clicking a spot, and the bulk-lookup button in the QSO table stayed grayed out. Both now work with any configured callbook (QRZ or HamQTH).
  • Calls with /P, /M etc. were not found on QRZ (reported 2026-06-06, already fixed in 1.18.0 — listed here for completeness): the lookup now falls back to the base call for portable/mobile suffixes and prefix notation.

Fixed in v1.18.0

  • The README inside the DMG falsely claimed "not notarized" for signed builds — the text now reflects the actual signing status (the fix had been waiting for a while and only takes effect from this DMG build on).

Fixed in v1.17.5

  • A second tune shortly after the first left CAT permanently dead (HB9HJL test of 1.17.4: the first tune healed itself ✅, the very next one didn't): the auto-reconnect's 30 s anti-loop guard blocked the healing. Now a budget of 3 reconnects in a row, refilled after 60 s of stable connection.

Fixed in v1.17.4

  • CAT still died after the tune cycle (3rd round with HB9HJL, Yaesu — despite the 1.17.3 tolerances, sometimes ~10 s after tuning without interaction): suspected rigctld serial desync. The app now automatically reconnects once (~2–3 s) when the connection is declared dead instead of showing "CAT err"; only an immediate second death (rig off, cable unplugged) shows the error message.

Fixed in v1.17.3

  • Switching spots right after a TUNE still dropped the CAT connection (follow-up report by HB9HJL after 1.17.2): after the tune cycle the rig keeps responding late for a while — a single polling timeout killed the connection. Now: 3-strike tolerance in the poll loop, automatic retry for frequency/mode commands, and status self-healing.

Fixed in v1.17.2

  • Clicking a spot changed the receive bandwidth on Yaesu rigs (reported by HB9HJL): along with the mode, the Hamlib default filter width was applied (e.g. ~1.2 kHz), overwriting the bandwidth selected on the radio. Spot clicks and mode buttons now leave the filter selection untouched.
  • TUNE dropped the CAT connection (reported by HB9HJL, Yaesu): during the ATU tune cycle the rig stays CAT-silent for several seconds — the app ran into a polling timeout and went offline with "protocol error: … Operation timed out". It now waits out the tune cycle and resumes polling normally.

Fixed in v1.17.1

  • One-click update still aborted with "The request timed out" (live report during the 1.16.0→1.17.0 update, despite the 1.15.0 retry/resume): the real cause was the download code itself — byte-by-byte processing throttled it to ~0.2 MB/s (70 s for 14 MB; curl: 1 s), and the stalled TCP stream triggered the timeout after 30 s of standstill. Now chunked: under 1 second. The update to 1.17.1 runs the old code one last time — workaround if needed: "Load in browser".
  • Persistently high CPU load (32–50%) with a connected cluster: three render hogs (heatmap recomputation per cell, window invalidation per spot, database scan per render in the "recent QSOs" panel) — now a stable ~6%.

Fixed in v1.17.0

  • The WWFF reference DB could not be loaded ("A server with the specified hostname could not be found"): the source wwff-cc.org no longer resolves via DNS. The download now uses the official directory CSV from wwff.co; if everything fails, the app shows a direct browser download link for manual CSV import.
  • WWFF parser: in the wwff.co format the state column (region) overwrote the active/deleted status — 1,349 deleted refs would have slipped through as active. Also: IUCNcat is now recognized, the plain-text country wins over the DXCC code.
  • POTA/WWFF/BOTA export failed with a portable call (e.g. HB9HJI/P as the log call): the slash in the filename was interpreted as a subfolder, the export silently failed — with the misleading message "no active log or missing write permissions". Filenames are now sanitized (HB9HJI-P@…) and export alerts show the actual error.
  • Callbook lookup with portable calls (BUG-20260606-0613-XF): HB9HJI/P, /M and prefix notation returned "not found" — now falls back to the base call.

Fixed in v1.16.0

  • The "ATNO only" filter in the POTA spots tab was missing although this help site already documented it — now implemented (together with "Manual only" against RBN noise).
  • Self-spot docs corrected: the spot button never worked in hunter mode (activator only) — help text and docs wrongly claimed it did.

Fixed in v1.15.0

  • One-click update aborted with "The request timed out" on unstable connections. A single network stall threw away the whole download. Now: up to 3 attempts with automatic resume at the drop point (HTTP range resume). The previous workaround was "Im Browser laden" (download in browser).

Fixed in v1.14.4

  • SWR display in the radio panel had disappeared (since 1.9.12). The SWR row only appeared after transmitting with a measurable SWR (> 1.0) — with a perfectly matched antenna it never showed up at all. Cause: the rework of the CAT capability detection in 1.9.12 lost the unlock-on-connect step. The row now reappears right after the CAT connect.

Fixed in v1.14.3

  • No fixes — mini feature release (Help menu → "HAM-Tools Help" opens the online docs in the app language).

Fixed in v1.14.2

  • One-click update hung at "Relaunching…" (1.14.0/1.14.1). The update was already installed correctly at that point — only the automatic relaunch never came: the open update sheet swallowed the quit command. Workaround when updating from 1.14.0/1.14.1: quit the app manually and reopen. From 1.14.2 onward the relaunch completes automatically (forced quit after a grace period + helper waits for the old process to exit).

Fixed in v1.14.1

  • No fixes — mini feature release ("Reset" button for skipped updates). Also the first live run of the one-click update introduced in 1.14.0.

Fixed in v1.14.0

  • No user-facing fixes — pure feature release (one-click update + English help site). Note: the new "Install now" flow ships with this release and will run for real for the first time with the next update — if anything snags, "Download in browser" always works.

Fixed in v1.13.0

  • No user-facing fixes — pure feature release (IC-705 WLAN control). Known limitation: the IC-705 allows only one network connection at a time; after an unclean disconnect the radio holds the session until it times out — then either wait a moment or toggle Network Control off/on at the radio.

Fixed in v1.12.1

  • No user-facing fixes — pure feature release (DXpedition alert in the DX cluster). One internal robustness fix only affects the development build.

Fixed in v1.12.0

  • Hexbeam calculation: the turning radius was slightly too large. The value was based on an approximation instead of the real original G3TXQ table. Corrected to 0.1539·λ; the info text and the vertical band spacings were adjusted accordingly.

Fixed in v1.11.1

  • The Hexbeam in the antenna simulator was only a simplified approximation (bidirectional pattern, front/back not trustworthy). The geometry was derived from a single radius instead of from the real curved "M/U" wire routing. The sim now uses the real, tuned G3TXQ geometry from the original EZNEC model (W driver + U reflector) — NEC-verified resonant with clear directivity (20m: ~10.5 dBi gain, ~10.5 dB front/back over ground). The "simplified model" note is gone.

Fixed in v1.11.0

  • Yagi / HB9CV / Moxon "Open in Sim" produced an almost bidirectional radiation pattern (barely any front/back). The velocity factor was counted twice — once in the build dimensions and again implicitly by NEC (which models the end shortening via the wire diameter itself). The antennas were thus ~5% too short, and the reflector lost its inductive effect. The simulation now uses the physical lengths without the extra factor. NEC-verified: Yagi front/back 3 → 27 dB, SWR of Moxon/HB9CV from ~13/7 down to ~1.2/2.0.
  • Magnetic Loop & EFHW shortening simulated without their reactance. The tuning capacitor (Magnetic Loop) and the loading coil (EFHW shortening) were discarded when the model was imported into the simulator — the antennas were therefore not resonant (SWR ∞). The lumped components are now carried over as well.

Fixed in v1.10.9

  • No fixes — pure feature release (internet/cluster connection indicator in the logbook top bar).

Fixed in v1.10.8

  • WSJT-X did not run in parallel with HAM-Tools (user report HB9HJL). As long as HAM-Tools was connected via CAT, it held the serial port exclusively — WSJT-X could not reach the radio. Now HAM-Tools' embedded rigctld can be kept open as a local server (127.0.0.1:4532) that WSJT-X & Co. attach to in parallel (Settings → CAT → "Share CAT"). The server stays alive even when HAM-Tools drops its own connection.
  • Yaesu: TUNE did not trigger a tuner match but switched the tuner off (user report HB9HJL). The TUN pill only toggles the tuner on/off. New: a separate TUNE button starts a real match on modern Yaesu rigs (AC002;). Hidden on rigs without a CAT tuner (FT-817/857/897) — the exact tune command is overridable per profile.

Fixed in v1.10.7

  • Moxon Rectangle produced an antenna ~24% too long. The constants in the calculator came from an unverified source and led to resonance at 11.4 MHz instead of 14.2 MHz (20 m). Now Cebik W4RNL MoxGen polynomials, dependent on wire diameter — verified against the official Cebik wire Moxon table. Material picker wire 2 mm / aluminum tube 12 mm + validity warning outside the model range.
  • POTA/WWFF/BOTA ADIF export wrote the multi-park list as a comma list in MY_SIG_INFO. But the upload platforms pota.app / wwff.co / wwbota.net require a separate file per activation target. Now: one ADIF per park/ref/bunker with a single MY_SIG_INFO, filename {call}@{ref} YYYYMMDD.adi. Activator call normalized consistently to the log's activator everywhere (solves the WSJT-X "STATION_CALLSIGN mixed" problem).
  • Spiderbeam multi-band Lel values were systematically too long. 23 table values (5-band, low-sun, WARC, original) corrected per DF4SA build manual v2.20 §2.3.2 ("Lel = table value − 8 cm" for insulated enameled copper wire).
  • Hexbeam calculator scaled all bands linearly from 20 m. Now band-specific values directly from the WiMo HEX6B build manual (G3TXQ Rev. V2.1) for 20/17/15/12/10/6 m, others via extrapolation.
  • Spiderbeam single-band could only do flat Yagi. Added V-shape mode with spreader half-arm, fixed "mm" → "cm" label, aligned multiband arm values.
  • HB9CV had no gamma-match design. Inner-conductor Ø, spacing and trimmer capacitance are now calculated, plus a material toggle tube/wire.
  • Groundplane: drift between app and web (1.02 vs 1.05) — both now consistently 1.02.

Fixed in v1.10.6

  • Second TRX did not connect / "Port busy" (user report HB9HJI). After a crash, force-quit or USB replug, a rigctld process stayed on the hard-wired TCP port 4532 and blocked new connections. The app now cleans up orphaned rigctld processes before every connection attempt (exact binary-path match via libproc).
  • Transceiver menu showed "Enable CAT" despite being connected. The entry was driven by an internal switch instead of the real connection → "enable" even when connected, and a click would disconnect. Now "Connect/Disconnect CAT" based on the actual state, consistent with the Start/Stop button.

Fixed in v1.10.5

  • IC-9700 did not connect over CAT (user report HB9HJI). With two Icom devices using CP210x USB (IC-9700 + IC-7610) on the same Mac, their ports were indistinguishable in the picker (usbserial-XXXXX) → the wrong one was chosen and rigctld aborted with "Exit -1". The port picker now shows the USB identity (CP210x serial number). Plus: the real rigctld error message (exit code + stdout/stderr) instead of "no stderr", a band-plausibility warning on a mismatching frequency, Icom flow control always None, CI-V placeholder = model default.

Fixed in v1.10.4

Three fixes from the live test (user reports HB9HJI) plus export-spec conformance:

  • Serial number not editable when editing. The contest QSO editor had no fields for serial/exchange — now Serial, Sent Exch and Recv Exch are editable (like the columns of the log table).
  • Contest rate far too high. "Rate 10/60 min" extrapolated over the span since the first QSO in the window (a few dense QSOs → absurd values). Now a fixed window width as the divisor (N1MM behavior).
  • DX cluster "Cont." filter filtered by the DX instead of by the spotter. "Cont. = EU" now shows only spots from spotters in EU (propagation view). The country column and Band Activity stay with the DX continent.
  • Export conformance (Cabrillo/ADIF/EDI). Cabrillo: CATEGORY-MODE: SSB instead of PH, new CATEGORY-ASSISTED/CATEGORY-TRANSMITTER, LOCATION: DX for international calls, invalid CATEGORY-TIME omitted. ADIF: MY_ANTENNA instead of the undefined ANTENNA. Cabrillo + EDI: CR-LF line endings. Checked against the WWROF v3, ADIF 3.1.5 and REG1TEST specifications.

Fixed in v1.10.3

  • EDI export: wrong scoring block for VHF contests. In the EDI/REG1TEST export the bands field of the count lines was wrong (CQSOs=n;0 instead of n;1; CWWLs/CExcs/CDXCs without a third field). Now matches the VHF Managers Handbook + RUMlogNG reference; checked against real IARU R1 145 MHz and DARC VHF logs. QSO lines, QRB distances and point totals were already correct.

Fixed in v1.10.2

Pure feature release (new "Recent QSOs" panel in the DX sidebar) — no bug fixes.

Fixed in v1.10.1

Three fixes from the live test of 1.10.0 (user reports HB9HJI):

  • ATNO falsely reported "NEW MODE". In the DX cluster the ATNO pill showed "NEW MODE" for entities long since worked in SSB. Cause: the sideband mode derived from the frequency (USB/LSB) was compared against the ADIF mode SSB from the log. Sidebands are now folded together (USB/LSB = SSB, CWR = CW, RTTYR = RTTY).
  • FT8/FT4 was shown as SSB/USB. The mode detection required an exact hit on the dial frequency; but FT8 signals are spread across the ~3 kHz wide AF passband above the dial QRG. Now the whole passband is recognized, plus added dial frequencies for 4 m and 2 m FT4.
  • The QRZ image area made the entry form jump. Without a loaded image the profile column did not hold its width — the fields jumped to the right, and back to the left with an image. Fixed image box with a placeholder, no more jumping. New: clicking the image opens it at triple size.

Fixed in v1.10.0

Core/refactor release — no classic bug fixes, but two scoring corrections that come with the new engine:

  • Canton/district multipliers with a full exchange. When the multiplier value sits as a token in a multi-part exchange (e.g. 599 ZH, 599 B07), it is now recognized correctly — previously the multiplier evaluated the whole field and therefore counted 0 (Helvetia/Christmas-contest cantons, WAG district).
  • USKA 50 MHz (CW/SSB): no more grid-square multiplier. The final score is the pure km sum per the official USKA regulations (previously incorrectly multiplied by grid squares).

Fixed in v1.9.18

Contest-scoring fix from the live test (user report HB9HJI):

  • Helvetia Contest score computed completely wrong. A 219-QSO log showed 411 pts × 23 mult = 9,453 instead of the correct 1,328 × 110 = 146,080. Three errors: (1) points counted HB QSOs as 1 instead of 10 and all non-HB flatly as 3 instead of 1 (same continent EU) / 3 (DX) — contrary to USKA regulation §2.7. (2) The multiplier counted only cantons and deduplicated them globally, instead of counting cantons AND DXCC entities per band. (3) The stats panel showed 23 instead of 66 cantons in the total row. Now correct, with a new "Entities" column and robust country resolution (HB→Switzerland, otherwise grid, otherwise prefix). DXCC prefix table extended by missing EU sub-prefixes (DL block, BE, NL, PL, BY).
  • Export buttons in outdoor logs showed the full DX/contest menu. In BOTA/POTA/SOTA/WWFF logs Cabrillo + EDI appeared (and ADIF for SOTA), even though the portals require other formats. Now log-type-specific: SOTA → CSV only, POTA/WWFF/BOTA → ADIF only, Standard/Contest → ADIF + Cabrillo + EDI.

Fixed in v1.9.17

Critical hotfix from the live test:

  • Outdoor log creation "Create" button silently disabled for unknown refs. All four outdoor wizards (BOTA/POTA/SOTA/WWFF) required a DB match on the entered ref. New refs (not yet in the bundled CSV) or unusual spellings led to canCreate == false, but the .borderedProminent button stays visually active — a click did nothing. Now a non-empty query is enough, the DB lookup is a bonus for auto-fill. Orange hint line when the ref is not in the DB.
  • Multi-ref hopping section was hidden for unlooked-up primary refs. It now appears as soon as a non-empty primary query exists.

Fixed in v1.9.16

UX hotfix from the live test:

  • The Outdoor tab opened the POTA sheet directly without a choice. Anyone wanting to activate SOTA, WWFF or BOTA first had to cancel the POTA wizard and re-navigate via the sub-picker. Now a program picker with all four options appears on the Outdoor click (when no outdoor log exists yet).
  • WWFF/BOTA logs were ignored on the Outdoor click. The "does an outdoor log already exist?" check only looked at POTA and SOTA — anyone with a WWFF or BOTA log still saw the POTA wizard. The order is now POTA → SOTA → WWFF → BOTA, so it switches correctly to any existing outdoor log.

Fixed in v1.9.15

Privacy hotfix — three forgotten setup leftovers with the author's call, caught retroactively on the first run of the new pre-release user-data check:

  • Sidebar subtitle "HB9HJI Funkwelt" hardcoded. In the main window at the top under "HAM-Tools" stood the author's call instead of a neutral or dynamically adopted value. Now dynamic from the station settings, empty when no callsign is set.
  • Previous-QSOs popover help text named "HB9HJI" as the example for the base-call match explanation. Switched to a generic "DL1ABC".
  • The QTH Locator field showed "JN47PN" as a placeholder without an "e.g." prefix — it looked like a default value. Standardized to "e.g. JN47PN".

Extends the privacy wave from v1.9.7 (five spots back then). The new pre-release check has been a fixed pipeline step before build-dmg.sh since today.

Fixed in v1.9.14

Outdoor-logger polish + 1 self-reported bug:

  • SOTA chaser logs could not be exported as CSV at all. The SOTACSVExporter checked "are there own summits in the log?" and, for chaser logs (which by definition have no own summits), silently returned an empty file list. So you had a cleanly kept chaser trip but no CSV to upload to sotadata.org.uk. Now its own chaser column schema + a new pre-export sheet with a role picker.
  • Per-summit activation status was summed across all summits of a log. With multi-summit hopping it showed "12/4 — activation valid", even though no individual summit had reached 4 QSOs yet. But the SOTA rule is per summit + UTC day separately. Now correct with a SOTASessionStatus helper and per-activation pills in the form.
  • WWFF activation status had the same bug (X/44 summed across all refs), and Hunter had no live status at all. Now solved analogously with WWFFSessionStatus + a Hunter block "N refs · M programs · R2R K".
  • POTA activation status as well (X/10 summed across all parks/days). Brought into line identically.
  • BUG-20260522-2040-AW: "Not all fields correct after a QRZ lookup" (HB9HJI, v1.9.12). In the standard log, after a second QRZ lookup the "Country" field kept the value of the previous station while other fields were correct. Root cause: clearCallbookFields() in QSOEntryPanel cleared 11 fields, applyCallbookResult() wrote to 12 — country was in the apply but not in the clear. One-line fix + symmetry invariant explicitly documented.

Fixed in v1.9.13

Contest-season cleanup + a few spec points we had been interpreting creatively so far:

  • Contest ADIF sent RST twice. STX_STRING/SRX_STRING contained the report again ("59 LU") in addition to the dedicated RST_SENT/RST_RCVD. The USKA/DARC cross-check doubled it during evaluation. Now only the exchange data (canton/state/grid/zone) in STX_STRING/SRX_STRING.
  • Cabrillo without a T column (Cabrillo 3.0 spec). Some contest robots rejected the files with "Parse error: missing T-field at column 80" because the transmitter-ID value at the end of the line was missing. Now 0 is appended automatically — and CREATED-BY switched at the same time from hardcoded "HAM-Tools 1.5" to dynamic BuildInfo.appVersion.
  • ADIF: MY_GRIDSQUARE only for POTA/SOTA QSOs. For normal DX and contest logs the field was missing entirely. LoTW therefore did no QRB cross-check for VHF QSOs (where the field is mandatory), and Club Log could not derive the geographic assignment for some awards (WAB etc.). Now written for every QSO, generically from the station settings.
  • Contest form: the cursor stayed on the exchange field after Enter. At 100 QSOs per hour a noticeable click/tab detour. Now @FocusState with the cursor jumping back to "Call" after each submit + auto-uppercase for canton/state/grid/zone (so "so" doesn't land lowercase in the log).
  • The USKA 50 MHz contest template had the wrong date + wrong time category. The date was on the 2nd weekend of June instead of the 3rd, the time category was 6 h instead of 24 h. Plus the template name was just "USKA 50 MHz" — now "USKA / IARU R1 50 MHz Contest" so it is clear which rule-set variant applies.
  • The RadioControlPanel footer had been static since 1.9.4. It permanently said "Idle — not connected" even when the CAT connection had long been up. A TODO from the CAT refactor that slipped through all the bug reports. Now the real CATController.Status in the footer.

Fixed in v1.9.12

Feature release — pure additions, no regressions from 1.9.11:

  • Logbook ADIF export was "all or nothing". Until now the "Export ADIF" button always exported the complete active log. Impractical for a lifetime log with a few thousand QSOs when you only wanted to upload a slice (a contest day, the last 50 QSOs for Club Log). Now: ⌘/⇧ click in the QSO table marks a selection, the button changes to "Export ADIF (N)" and writes only those N rows.
  • The CAT panel had no sliders for volume and TX power. The RUMlog/HamLog models show AF/RF sliders — we only had mode/VFO/split buttons. Now two new sliders between the S-meter and the status badges. Drag-and-release pattern: during the drag the update runs locally, on release it goes to the rig once — saving round-trips.
  • SWR was nowhere visible. On every TX you had to look at the rig display to see whether the standing-wave ratio was okay. Now a live SWR bar in the panel during transmit, color-coded (≤ 1.5 green, ≤ 2.0 yellow, > 2.0 red).
  • TX/RX badges were placeholders. The two small RX / TX pills next to the PWR value had no live read and always stayed gray. Now the app reads the PTT status (t command) on every poll tick and colors the badges accordingly — whether the PTT comes from the mic, data or CAT.
  • No quick DSP toggles. Standard functions like Noise Blanker, Noise Reducer, Auto-Notch and antenna tuner were only reachable at the rig — with a faint CW station coming in you waste time at the knob. Now four toggle pills under the status badges; a click toggles the function at the rig.

Fixed in v1.9.11

Live-test feedback from 1.9.10 (5 bug mails via the in-app reporter):

  • Previous popover found no /P /M /QRP QSOs (BUG-20260521-2000-QP). LogbookDatabase.findQSOs(matching:) compared calls exactly — anyone searching for "HB9XYZ" found no "HB9XYZ/P" entries even though they were in the log. Now base-call match: the longest part between the "/" separators is compared on both sides. The empty state additionally diagnoses "X logs searched · base-call match".
  • "Fetch QSL confirmations" hidden only in the QSL tab (BUG-20260521-1958-WJ). Users looked for the buttons in the settings, where the credentials also live. The buttons are now mirrored in Settings → Lookup & Upload → QRZ.com / LoTW, with the hint "(also available in the QSL tab)".
  • Contest cluster lacked a worked filter + mult marking (BUG-20260521-2005-CT). In contest mode a filter bar now appears at the top with a toggle "👁 Hide worked" + a conspicuous green "MULT" badge next to multiplier candidates + a color legend. Appears only when activeLog?.type == .contest.
  • Frequency entry did not control the radio (BUG-20260521-1937-SS). The text field in RadioControlPanel was editable, but commitFreqText() only set radio.frequencyMHz locally — no cat.setFrequencyMHz(). The poll loop overwrote the value ~200 ms later with the real radio frequency, so from the user's view "nothing happened". Now the commit sends the frequency to the radio when CAT is active, with an optimistic UI update to avoid flicker.
  • The USB port had to be re-selected after every reboot (BUG-20260521-1954-YH). With FTDI/CP210x chips macOS may assign the stick a different path suffix after boot; the stored path was then dead and Connect failed silently. New SerialPortDiscovery.resolve(stored:) logic: if the path is gone and exactly one USB serial port is present, it is adopted automatically + persisted in CATSettings (info toast "ℹ️ USB path migrated: old → new"). On ambiguity, a clear error message with a candidate list.

Fixed in v1.9.10

  • LoTW path setup was terminal-heavy. The "tqsl binary" field in the LoTW settings was a plain text field — when the auto-detection did not find the app (TQSL.app instead of Tqsl.app, an unusual install location, Homebrew), the user had to hunt for the path with mdfind or find in the terminal. Now a "📁 Browse…" button to the right of the field that opens a Finder picker and automatically extracts the binary from the .app bundle.
  • Yaesu voice-memory V5 slot was missing. The TRX voice-keyer row showed only V1–V4 for Yaesu profiles, even though the supported models (FT-991/A, FT-710, FTDX-10, FTDX-101D/MP) have 5 slots in hardware. A fifth button added — the code comment even pointed at the "we only map 4" TODO itself. ICOM stays at 4 slots (hardware limit).

Fixed in v1.9.9

  • The Schedules tab was a placeholder with no content. The tab bar showed "Schedules" with a calendar icon but a disabled tooltip "coming in a later phase". The tab is now fully implemented: skeds + DX events with a countdown, QSO-form pre-fill, cluster filter, status menu and macOS notifications. Persisted in ~/Documents/HAM-Tools/Cache/schedules.json. Docs under Modules → Schedules.

Fixed in v1.9.8

  • The TRX voice-keyer UI was ICOM-only. The V1–V4 buttons in DX/contest/outdoor forms showed "ICOM Voice / IC-7300/7610/9700/705" and were silently meant for ICOM only — Yaesu/Kenwood/Elecraft users could not click to see whether their Hamlib backend supported it by now. Now brand-specific display, with the buttons always active as long as CAT is connected.
  • RPRT -11 in the status line was cryptic. For voice-memory calls that the Hamlib backend does not implement, "sendVoiceMem rejected: RPRT -11" appeared. Now an understandable message: "This function is not (yet) supported by the Hamlib backend for this TRX model."

Fixed in v1.9.7

  • Privacy leak: the DXCluster default callsign was hardcoded HB9HJI, the QTH locator hardcoded JN47PN in five places (cluster, world map 2×, QTH locator, grayline), and the API user agent contained "HAMTools/2.0 HB9HJI". On a fresh install without an entry in the station settings, other users started with the author's identity in the cluster login + distance calculation; on every API request to pota.app/sotadata.org.uk/wwff-cc.org the author's call was sent in the HTTP header. All defaults set to "", the user agent is now HAMTools/<appVersion>.
  • Cluster spot time mismatch (BUG-20260520-1945-JS): depending on the source, the spot list showed Mac local time, RBN skimmer "UTC" strings with local content, or no time zone at all. Now DXSpot.displayTime always renders from the timestamp date in UTC (HHmmZ).
  • Mode multi-select + band sorting (BUG-20260520-1943-G8): the mode filter was single-pick, now multi-select (Set<String> with migration). The band filter list is sorted by wavelength instead of alphabetically.
  • TRX setup submenu closes (BUG-20260520-1942-B3): CATController as an @ObservedObject in TransceiverCommands triggered per-second CommandMenu rebuilds via the status poll loop. Now a let reference, the status is read only on click.
  • Spot cap too small (BUG-20260520-1942-AA): SpotPersistence.maxSpots 500 → 2000. On a contest weekend with 4+ DXSpider nodes, 500 were full in ~50 s.
  • Grayline performance (BUG-20260520-1940-33): nightCells was a computed property → 2592 polygon constructions per body render. Now a @State cache with recompute only in onAppear/onChange. Plus grid step 5° → 10° (648 instead of 2592 polygons).

Fixed in v1.9.6

  • LoTW: the station-location picker found no locations configured in tqsl 2.5+, because only the old path ~/Library/Application Support/TrustedQSL/station_data.xml was tried — current tqsl stores them under ~/.tqsl/station_data.xml. A second path candidate added; the picker now automatically shows what was set up in the tqsl GUI.
  • LoTW: tqsl exit codes 9 and 10 were swapped. A tester with an incorrectly entered station location got "LoTW server not reachable" instead of the correct "Location not found" message. Mapping verified from a tqsl 2.8.4 live test: 9 = CONNECTION_FAILED, 10 = COMMAND_ERROR.
  • LoTW: "Station Location X could not be found" landed in the generic CLI-argument error branch and showed an unhelpful text. A dedicated plain-text detection in interpret() now outputs "check in Settings → LoTW" directly.

Fixed in v1.9.5

  • LoTW upload reported "Network: LoTW server not reachable" even though the upload actually succeeded. Cause: the word "Connection" in an intermediate tqsl log line triggered the network branch in interpret(). The success plain-text match ("uploaded successfully" / "queued for processing") now runs BEFORE the network heuristics. In addition the subprocess now starts with an explicit HOME/PATH + cwd=$HOME (some app-sandboxing scenarios delivered an empty environment that confused tqsl). Error alerts now show the last 500 characters of the raw tqsl output as a diagnostic aid.

Fixed in v1.9.4

  • LoTW upload: tqsl exit codes were mapped to the old 1.x scheme (0/3/4/6) — the current tqsl 2.5+ version uses codes 0–11 with completely different semantics. The UploadOutcome on success/duplicate/network error was therefore unreliable. Codes re-derived from the tqsl source (apps/tqsl.cpp), duplicates additionally detected by text match in stdout (tqsl 2.5+ no longer signals them via exit code).

Fixed in v1.9.3

  • Startup crash on macOS 26.3.x: HAM-Tools.app crashed immediately after login with EXC_BREAKPOINT in SCPService.loadRawFile. The cause was a forgotten Bundle.module direct call — the tolerant AppResource helper (built in 1.8.16 for exactly this class of bugs) was overlooked in the new contest SCP code. Now switched over; SCPService finds the MASTER.SCP file regardless of bundle format (flat or canonical Contents/ layout). Testers who could no longer start after 1.9.2: load 1.9.3 manually, after which auto-update works normally again.

Fixed in v1.9.2

  • The right sidebar still jumped to varying widths after the 1.9.1 release as soon as you switched between Contest and Standard/Outdoor. Cause: HSplitView identified ContestStatsPanel and PropagationPanelView as two different child views and reset the splitter on every switch. Both panels now sit in a shared outer VStack, with the frame modifier on the outside — so HSplitView always sees the same view identity. Frame additionally pulled in tighter (min 230 / ideal 255 / max 290).
  • The ICOM voice-keyer brand restriction was only visible via a .help() tooltip on the text label. SwiftUI on macOS triggers the hover tooltip on plain text views unreliably — users therefore did not see the restriction. The model list is now inline as a second text view next to "ICOM Voice": IC-7300/7610/9700/705.

Fixed in v1.9.1

  • Light theme: the CAT frequency display was invisible, black-on-black — the foreground hung on theme.textPrimary (nearly black), the background on theme.bgLog (nearly black). Switching to theme.logText (green radio display) makes the display consistently readable in all themes.
  • Light theme: the sidebar headlines (Send DX Spot, Propagation, Solar Data, My Spots, Band Activity) were barely readable in light pastel gold on a white panel. In the light theme now theme.accentOrange (#E07000) as the headline tone; Dark/Ham Classic stay unchanged at the classic gold, Matrix uses the cyan accent.
  • The contest wizard did not save the band category chosen in the Cabrillo picker — the value was lost on creation, and the cluster filter and Cabrillo export always fell back to the template default. Schema v12 migration adds log_meta.contestBandCategory; all three consumers (cluster tab, export sheet, stats panel) now read the log value first.
  • The right panel jumped to up to 340px ("too wide") when switching between DX/Outdoor/Contest. Both sidebar variants (Propagation, Contest Stats) now use identical frame values (min 250 / ideal 285 / max 320), so HSplitView can no longer pull to the upper stop.
  • The "Band Activity" headline wrapped to two lines on a narrow sidebar (the picker with width: 100 left too little room). lineLimit(1) + the picker narrowed to 88px — the headline stays strictly single-line.

Fixed in v1.9.0

  • DX cluster heatmap picker (Band Activity, right panel): the 15/30/60-min choice only had a visual effect — the numbers in the heatmap kept computing with the old value. The picker in the panel and the bandMatrix calculation were decoupled across two independent states. Now a computed property directly in the panel, AppStorage-based. Plus a "5 min" option, so that with a full cluster (~500 spots in the 15-min retention) you can see a difference at all.
  • The app was not launchable in English (and was never really English). Three bugs at once: SwiftPM does not automatically compile the string catalog into its runtime form; the generated localization files landed only in the SwiftPM sub-bundle (invisible to SwiftUI); Info.plist lacked the CFBundleLocalizations/DevelopmentRegion entries. All three places fixed — the language picker in the Appearance tab now does what it should.
  • DX map QTH centering did not take effect after an interactive camera move: MapCameraPosition.region was discarded by SwiftUI as "equal" when the user had previously moved the map manually. Now with a .camera(MapCamera(...)) snapshot, it animates cleanly back to your own QTH.

Fixed in v1.8.16

  • Callbook lookup: when clicking a new cluster spot or on a manual call change + Tab, the First/Last/Street/City/State/Email/Locator/zones of the previous station stayed put, even though the image and header already showed the new station. applyCallbookResult only filled empty fields; now a shared helper clears up before every fresh lookup.
  • Radio/CAT frequency display: the right segment was only 2 digits (10 Hz resolution) — "7.095.00". Now 3 digits with full 1 Hz resolution: "7.095.000".
  • The program maps (POTA/SOTA/WWFF/BOTA) had the same MapKit-stall risk as the History tab before 1.8.15. The hard cap + overflow banner is now extended to all program maps.

Fixed in v1.8.15

  • History tab crash: with "Period = All" and a large standard log, the app could completely "disappear" when clicking the History tab — the process kept running, but no window was visible anymore. Cause: a MapKit render stall from too many annotations + polylines. Three protective layers: a hard cap on 1500 annotations, a line limit of 500, and the "All" option removed from the period picker (max "2 years").

Fixed in v1.8.13

  • The auto-update check reported "HAM-Tools is up to date" even though a newer version was available on the server — isNewerBuild() compared only the build date as a string, so hotfix releases from the same day (1.8.11 → 1.8.12 → 1.8.13) were not detected. Now a numeric semver comparison is primary, the build date only as a tiebreaker. Effective from the 1.8.13 build — anyone on 1.8.12 or older must update manually once from /app/dmg/latest.dmg.
  • Multi-cluster: host or port changes to an already active cluster node were ignored by the pool resync (the old client kept running). applyActiveNodes() now does a field diff and selectively restarts affected clients.

Fixed in v1.8.12

  • App startup crash on macOS 26.5 (real cause): macOS 26.5's Bundle.init(url:) returns nil for SwiftPM resource bundles in some setups — Bundle.module then falls back to its fatalError fallback and the app crashes directly in BOTARefService.init. The 1.8.11 fix (rebuilding the bundle format canonically) did not fix this. From 1.8.12 Bundle.module is bypassed entirely: a new AppResource helper searches for the resource bundle itself, tolerates different bundle layouts and returns nil instead of crashing.

Fixed in v1.8.11

  • App startup crash on macOS 26.5 (first attempt — see v1.8.12 for the real fix): bundle-format correction in build-dmg.sh. On its own it did not yet bring success, but it remains in the build for clean code-signing hygiene.

Fixed in v1.8.10

  • POTA ADIF upload rejected with "Only a single STATION_CALLSIGN value is supported per log file" — when logging FT8 over WSJT-X spots, the my_call could switch mid-session from the home call to the portable call (e.g. HB9HJIIT/HB9HJI/P). Now two safeguards: the WSJT-X importer always takes the activation callsign chosen in the log wizard for outdoor logs; in addition the POTA export also unifies old mixed logs.
  • The mode picker in the Radio/CAT panel was dimmed and not clickable without a CAT connection — logging without a radio (e.g. a remote/travel setup) was thus nailed to the last active mode. Now always clickable; without CAT, FT8/FT4/JT65/JT9/PSK31/JS8/Q65/MSK144 are additionally selectable (Hamlib does not know these directly — they run at the TRX over PKTUSB).

Fixed in v1.8.9

  • Club Log upload: 403 Forbidden for email addresses with @ and other special characters — the form encoding was not RFC-3986-compliant and was blocked by Club Log's nginx WAF. Now strictly RFC-3986-encoded.
  • The standard DX log warned "Already worked" on repeated logs of the same call (lifetime log/regular net/daily log) — pointless there. The dupe warning is now only in program logs (POTA/SOTA/WWFF/BOTA) and contests.

Fixed in v1.8.8

  • POTA ADIF upload was rejected by pota.app — the export used the older undocumented field MY_POTA_REF. Now standard-compliant with MY_SIG=POTA + MY_SIG_INFO.
  • WWBOTA ADIF: the old stub produced no uploadable file — now the official format with MY_SIG=WWBOTA and a comma list in MY_SIG_INFO for multi-bunker.
  • POTA multi-park hopping: pota.app refused comma lists in MY_SIG_INFO — the export now automatically writes a separate file per park.
  • QRZ auto-fill in POTA/SOTA/WWFF/BOTA logs adopted only the name, the rest stayed empty — the ADIF was DXCC-incomplete. Now additionally QTH, locator, country, continent, CQ/ITU zone.
  • The hopping field on log creation showed only checkmarks without context — now the full name + details (park/summit/bunker) per entry.
  • The band plan was a cramped sub-tab in the logbook — now its own window (⌘⇧P, menu Window → Band Plan Window).

Fixed in v1.8.7

  • The update system compared the minimum macOS version as a string — "10.9" would have falsely counted as higher than "10.15". Now a strictly numeric version comparison.
  • The incompatible-update dialog showed an enabled "Open download" button even though the DMG would not run on the system. Now disabled with a clear reason.

Fixed in v1.8.6

  • FAQ link "Undo updates?" pointed to /app/dmg/ — the path returned 403 instead of a version listing. Now a directory index of all DMG versions.
  • The top-nav download pointed to a version-specific DMG and went stale with every release — now a version-less latest.dmg with an auto symlink.

Fixed in v1.8.5

  • The bandmap was restricted as a sub-tab in the logbook — now additionally openable as a pop-up window per band, with several visible in parallel on a second monitor.
  • DX propagation: no global day/night view — a new grayline map as its own window.
  • The settings gear in the logbook top bar was easily overlooked — removed, settings now via the app menu "HAM-Tools → Settings…" (⌘,) or the Transceiver menu.

Fixed in v1.8.4

  • The CAT connection dropped after a QSY or mode change — a race condition between the poll loop and write operations on the same rigctld TCP socket. A new client lock in the CATController serializes all operations.
  • A spot click forcibly switched from the DXClusters sub-tab to the Log sub-tab. You now stay where you are — the draft fills in the background.
  • The DX cluster table showed "SSB" as the mode, even though LSB/USB is correctly derivable depending on the band (now automatic).
  • The "Settings…" entry in the Transceiver menu did not respond (the old NSApp selector replaced by the SwiftUI API).
  • 13" MacBook Air layout: the right sidebar (Propagation/Solar/Band Activity) did not fit on the screen, you had to scroll.

Fixed in v1.8.3

  • The BOTA map sub-tab appeared incorrectly in the standard DX log (only meaningful in the BOTA program log)
  • The "New Contest" sheet was too small → the buttons "Cancel / Create" were cut off in the categories step
  • The POTA columns "State" and "Their Park" were shown in the standard log, even though they only make sense in POTA logs
  • The QSO table's column selection was only reachable via header right-click → a new "Columns" button in the toolbar with all 32 columns + reset
  • The spot tables (DX/POTA/SOTA/BOTA/WWFF) had no reorder/hide-show function → switched entirely to a SwiftUI Table

Fixed in v1.7.1

  • A cluster click did not fill the contest/POTA form — a race condition between QSOEntryPanel and the specialized form
  • The mode picker in the contest showed all modes instead of only those matching the Cabrillo mode category
  • The "New…" button for a CAT config did not copy the serial port along with it
  • The DX cluster in the contest showed spots in all modes instead of only the contest mode

Fixed in v1.7.0

  • The sidebar with 42 tools was cluttered → 3 top items (Logbook / DX Cluster / Calculators) with an accordion
  • The band plan was its own sidebar entry → moved into a logbook sub-tab
  • The DX cluster only connected on a tab click → now globally at app start

Report a Bug

In the app: Cmd+Shift+B or menu bar → Help → Report Bug… By mail: bugs@funkwelt.net

HAM-Tools © HB9HJI · Funkwelt