What is and isn't fixed
A fork that lists only what it improved is advertising. This page is the other half: what is wrong with this firmware today, measured, with the ticket that tracks it. Nothing here is theoretical — each line is something observed on a running board.
The serial console needs a certificate your browser trusts
Section titled “The serial console needs a certificate your browser trusts”Every other tab works over a self-signed or internal-CA certificate once you
accept the warning. The console does not. A browser will not open a
WebSocket to a certificate it does not trust, and the exception you granted by
clicking through on the page does not extend to that connection — so the
console reports not connected, close code 1006 while the rest of the
interface is fine.
Measured on 2026-09-12. What the browser reports:
webSocketCreated wss://<board>/api/bmc/serial/ws?node=0webSocketFrameError net::ERR_SSL_PROTOCOL_ERRORThe board is not at fault. The same endpoint, from a client with verification
off and a valid token, answers handshake: OK.
Two ways round it, both of which work today:
- Trust the authority that issued the board's certificate in the browser's own store. A click-through exception is not enough; the certificate has to be trusted.
- Reach the board through a proxy that terminates TLS on a certificate your browser already trusts. That is what one page over every board does.
The interface says this now, in the panel under the console. It cannot detect the case — a browser reports no reason for a failed handshake — so it names the cause that is usually right rather than guessing.
Anything local is trusted
Section titled “Anything local is trusted”/api/bmc skips authentication entirely for requests from 127.0.0.1. That
is how the on-board tpi works without credentials. It also means any
process on the board can power off a node or stage firmware, with no
credential and no audit line.
Since v2.15.0 the on-board tpi is the only thing that relies on it.
The promotion gate used to need the bypass as well, to mint itself a metrics
token; /metrics moved to its own listener and takes no credential, so the
gate now makes one plain request and needs nothing.
Since v2.14.0 the bypass at least leaves a trace: every mutating call writes an audit line, and one that skipped authentication says so in plain words rather than being folded in with a real credential.
Sep 9 15:12:41 hive-bmc authpriv.info bmcd[812]: power by loopback (unauthenticated) from 127.0.0.1: okThat is a smaller thing than removing the bypass, and it is not a substitute for it. It means an unauthenticated power-off can be found afterwards, not that it can be prevented.
The forced password change shipping in the next release does not fix this and does not try to: loopback is exempt from it, for the same reason the bypass is hard to remove — a process on the board is already root on the board. The two faults look alike and are not the same one.
Tracked as SQU-165 (a Unix socket authenticated by peer credentials, so the bypass can be removed rather than merely narrowed) and SQU-113.
Flashing a module may not target the module you chose
Section titled “Flashing a module may not target the module you chose”On v2.5 boards, tpi flash and the interface's flash page write to
whichever module is in maskrom first and report success — whatever was
selected. With one module in maskrom this is correct; with two it is a
coin toss, and the cost is a module that no longer boots.
v2.14.0 changes the mechanism and has not yet been proven on hardware. The daemon now accepts a module only on the hub port the board's own device tree says that node is wired to, and refuses anything on another port instead of writing to it:
node 3 requested on 1-1.3; found Rockusb on 1-1.1 insteadWhat is proven is that the device tree says node N is port N — it is read at runtime, and a unit test builds a tree wired the other way round and requires the other answer. What is not proven is that the device tree agrees with the physical wiring, which needs two modules in maskrom at once to test. Until that is done, the interface keeps its red warning: put only the target module into maskrom before installing.
Tracked as SQU-105.
Flashing a module in slot 1 or 2 fails when a mini-PCIe card uses USB
Section titled “Flashing a module in slot 1 or 2 fails when a mini-PCIe card uses USB”Hardware; no firmware fix. Reported 2026-10-15.
tpi flash and the interface's flash page fail on node 1 or 2 with
"Compute module's USB interface not found or supported" when a USB device sits
in that node's mini-PCIe slot. The report that found it was an RK1 in slot 2 on
a v2.4 board with a Zigbee stick in the slot. The board's dmesg showed the
module's high-speed enumeration failing again and again with error -71, then
"unable to enumerate", while a full-speed non-Rockchip device (1a86:7523, a
CH340) on the same lines enumerated without trouble. A VID:PID that is not
Rockchip's, next to error -71, is the signature.
The cause, as far as I can tell: the mini-PCIe slots of nodes 1 and 2 carry USB 2.0, and a device there shares the USB pair the BMC uses to flash the module. Two devices on one pair and the module cannot enumerate. This is electrical. The BMC has no control over the slot's power, reset or USB lines on v2.4 or v2.5; v2.5 has a per-node USB hub on the BMC side, but the clash is on the node side of its port. This rests on the one report and on the firmware source and factory tests. I have not seen a schematic that confirms it.
Two ways round it:
- Power the node off, remove the mini-PCIe USB card, flash, and put it back.
- Move the module to slot 3 or 4 and flash it there.
v2.44.0 changes the message, not the hardware. Flashing waits up to 15 s for the module's USB boot device, where it used to look once, a second after power-on. When the device does not appear, the error names the other USB devices it saw on the node and says that a device in the node's mini-PCIe slot may be in the way. A failed or cancelled flash now powers the node off and restores the USB route, instead of leaving the node in flashing mode.
Nothing shuts the board down if it overheats
Section titled “Nothing shuts the board down if it overheats”The thermal zone declares four active trips — 20, 45, 60 and 70 °C, each
driving the fan a step harder — and hot at 95 °C. There is no critical
trip, and hot notifies without acting. So if the fan fails, or is held low,
the board climbs with nothing to stop it.
This is not a regression and not something this fork introduced; it is what the device tree has always declared. It is written down here because the fan can now be held at a step from the interface, and a person doing that should know what is and is not underneath them. The daemon takes a held fan back above 70 °C for exactly this reason — but that is a daemon that has to be running, which is a weaker guarantee than a kernel trip.
No ticket yet. A critical trip is a device-tree change and wants a decision
about what it should do at what temperature, not a number picked here.
There is no watchdog
Section titled “There is no watchdog”Everything above has the same last resort: a person walking to the rack. The SoC has a hardware watchdog and this firmware does not arm it, so a BMC whose userspace dies stays dead until someone cuts its power.
Tracked as SQU-106, and it is the most valuable unbuilt thing on the list.
The board forgets everything at every reboot
Section titled “The board forgets everything at every reboot”Reported 2026-10-07, by one reader, on a v2.4 board running v2.42.0.
The symptom is the factory-password page and a new self-signed certificate after a reboot, and again after the next one. Nothing you change survives. It is easy to mistake for the old card-install reset (below), because an upgrade is the usual reason the BMC reboots.
To check, log in over SSH as root:
# mount | grep ' / 'overlay on / type overlay (...,upperdir=/tmp/safemode/upper,workdir=/tmp/safemode/work)# dmesg | grep -i ubifsUBIFS error (ubi0:2): ubifs_recover_leb: LEB 16 scanning failedupperdir=/tmp/safemode/upper means the root filesystem's writable layer is in
RAM. The cause, from reading the firmware's /sbin/preinit and
/sbin/mount_overlay: at boot, preinit mounts the UBI volume overlay (UBIFS)
at /mnt/overlay and uses it as that writable layer. If the mount fails, it
enters safe mode without saying so: the layer becomes a tmpfs, the root
password is the factory turing, a fresh certificate is generated, and nothing
survives a reboot. So every reboot is a factory reset. The board gives no
warning today; the factory-password page is the only sign. Holding KEY1 at
power-on also enters safe mode, on purpose; /proc/cmdline then says
safemode, and that is not this fault.
My guess at the cause is a power cut while UBIFS was writing. That is one report, and I have not reproduced it. As far as I know it is not specific to v2.4. The flash's own counters, below, make a single interrupted write more likely than failing flash.
The firmware does not warn when this happens yet. Fixing that is planned; I am not promising a version.
To check your flash, read its error counters:
# grep . /sys/class/mtd/mtd*/ecc_failures /sys/class/mtd/mtd*/corrected_bits /sys/class/mtd/mtd*/bad_blocksOn the reader's board they were clean: ecc_failures 0, corrected_bits 1,
bad_blocks 1.
The repair is the firmware's own first-boot path: when no overlay volume
exists at boot, mount_overlay creates a new one. Over SSH as root:
# ubirmvol /dev/ubi0 -N overlay# rebootThe settings in the damaged volume are already unreadable, so nothing readable
is lost. You can try a read-only rescue first, mkdir /tmp/old && mount -t ubifs -o ro /dev/ubi0_2 /tmp/old,
but expect it to fail the same way. After the reboot, set the password again,
check that mount | grep /mnt/overlay shows ubifs, and reboot once more to
confirm it persists.
Without SSH, install from an SD card from v2.42.0 with a factory-reset.txt
next to install.txt. A plain card install from v2.42.0 does not help: it
keeps the settings volume when its UBIFS superblock is intact, and here the
damage is deeper.
2026-10-07: the repair is confirmed on the reader's board as far as the
volume goes. After ubirmvol and a reboot, /dev/ubi0_2 is mounted at
/mnt/overlay as ubifs, / uses upperdir=/mnt/overlay/upper, and the
kernel log shows UBI attaching with corrupted PEBs: 0 and UBIFS creating a
fresh 26 MiB overlay with no errors. The flash counters were clean. Still to
be reported: that a newly set password survives the next reboot.
Fixed, and worth knowing about
Section titled “Fixed, and worth knowing about”The web interface skipped the image check on every module flash
Section titled “The web interface skipped the image check on every module flash”Affected BMC-UI 3.25.0 through 4.0.1, which is firmware v2.26.0 to v2.42.0;
fixed in v2.43.0. Flashing a module from the web interface never checked the
image's CRC, whatever the "Skip CRC" box said. The interface always sent
skip_crc, true or false, and the daemon looked only at whether the key was
there, not at its value.
BMC-UI 4.1.0 sends skip_crc only when the box is ticked, and bmcd 2.39.0 reads
its value. tpi was not affected: it sends skip_crc only when asked.
If you flashed modules from the web interface on those releases and have any
doubt about an image, flash it again after upgrading, or compare the file with
its published checksum before you do. If you use tpi, nothing changes. In the
same release a sha256 given for an image already on the board (the SD card or
local) is verified; before, it was accepted and ignored, and only uploads and
URLs were checked.
The range is measured from the tags: v2.26.0 is the first firmware tag whose
bmc-ui.mk pins BMC-UI v3.25.0, and v2.42.0 is the last, pinning v4.0.1.
Checked 2026-10-15.
Flashing a module from the SD card failed with 411
Section titled “Flashing a module from the SD card failed with 411”Affected BMC-UI 3.25.0 through 4.0.1, firmware v2.26.0 to v2.42.0; fixed in
v2.43.0. Choosing an image on the card and pressing flash was refused with
411 and Invalid length query parameter. The interface sent the card's file
as if it were an upload, and the daemon rightly wanted a length. A user report
on Discord is how I learned of it.
From v2.43.0 the interface asks the daemon to read the file from the card
(sdcard=1&file=<path>), confined to the card, and the progress bar shows a
real percentage. The picker's Choose button also stays on screen with a long
filename, and a failed flash says why in words rather than raw JSON.
Before the fix the way round was the command line, which always worked:
tpi flash --local /mnt/sdcard/<file> -n N.
Installing from the SD card reset the password, the certificate and the settings
Section titled “Installing from the SD card reset the password, the certificate and the settings”Affected every release up to and including v2.41.0; fixed in v2.42.0. The
card is an installer, and the installer formatted the board's whole UBI
partition, so a card install was a factory reset: the root password went back
to turing, the board generated a new self-signed certificate, and the
network, NTP, fan and node settings were gone. The installer is upstream's, and
every release of this fork shipped it unchanged. A reader reported "password
reset back and new self signed cert" after an upgrade on Discord, which is what
a card install does. The .tpu upgrade always kept the settings.
From v2.42.0 the installer is this fork's own
(BMC-Installer). It keeps
the board's overlay volume when it can verify the volume is intact and that
the kernel will attach it, and refuses to keep anything the kernel's own UBI
checks would reject. Otherwise it erases as before and says why on the serial
console. A factory-reset.txt file on the card, or typing ERASE at the
prompt, forces the reset. A card written from v2.41.0 or earlier still erases.
The install page has the
steps.
Verified 2026-10-06 in simulation (the kernel's nandsim in CI), not yet
through an SD card on a physical board.
Naming a VLAN made the switch card refuse to check the layout
Section titled “Naming a VLAN made the switch card refuse to check the layout”Affected v2.33.0 to v2.38.0; fixed in v2.39.0 (#59). Type a name beside a VLAN in the switch card and Try it and Apply greyed out, under the line "This board cannot check a configuration before it is applied." Clear the name and they came back. A reader took the line at its word and asked whether his board revision lacked the feature. It did not; the daemon had refused the question.
The cause is a corner of how the daemon reads a request. validate and
PUT accept either a preset or a whole document, and the type that says
"either" makes the parser buffer the body before deciding. In the buffered
form a map key "50" is a string that never becomes the number the names
table is keyed by — so a document with no names read fine, and a document
with one name was refused as "did not match any variant", on both
endpoints, from the day names existed. Reproduced on a board with the same
document twice: names: {} accepted, names: {"1": "test"} refused.
The daemon now reads the names by their wire form — string keys, parsed — so both paths agree. A test feeds a named document through the "either" type and fails on the old code with the reporter's exact message. Checked on a board after the flash: the reporter's exact request answers 200. (A key that is not a VLAN id at all still gets the generic "did not match any variant" through the endpoint rather than a message naming the key; no client sends one, and the earlier draft of this entry claimed otherwise.)
And the line was wrong to say what it said. The interface showed the same sentence for a daemon with no validate endpoint and for a daemon that had one and rejected the request; only the first means "cannot check". From BMC-UI 3.38.0 a rejected request shows the daemon's own words instead — "The board refused the question rather than the layout: …" — so the next reader is told which it was.
The password form would not accept typing
Section titled “The password form would not accept typing”Affected every release from v2.28.0 to v2.36.0; fixed in v2.37.0 (#48). The three boxes of the password form looked normal, focused normally, and refused every character. Nothing was reported, because from the browser's point of view nothing went wrong: the keystroke arrived and the interface put the old value straight back.
The cause is one clause in the shared text field, which dropped the change handler for password inputs. A React field that holds its own value and cannot report a change is read-only by construction. The file input is in the same clause for a real reason — its visible box is written by the hidden one beside it — and password was swept in with it, in a commit that predates this fork.
What it cost. The password card on the Access tab, from v2.28.0. And
from v2.33.0 the page a board still on its shipped password shows instead
of everything else, which means such a board could not be taken off that
password from a browser at all — only over SSH, with passwd. That is how
it was found and reported.
Why nothing caught it. It compiles, it lints, it renders, and the page-length gate measures height. Logging in was unaffected, so the one password box anybody used daily was the one that could not break: that form reads the page on submit rather than holding state.
The interface's CI now types into every visible box of every tab in a real browser and fails on one that does not keep what was typed. It was checked against the unfixed component, where it names exactly those three boxes, and against a real board before and after the fix — the demo build and the bundle a board serves are different builds, and only the second one answers for a board.
Every board shipped with the same password, and kept it
Section titled “Every board shipped with the same password, and kept it”Fixed in the next release (SQU-275). A board leaves the factory as root /
turing. It is printed in the quick-start guide, it is identical on every
board anyone has bought, and nothing ever asked for it to be changed — on a
project whose own front page says a board should not face the
internet. Upstream has had an issue open
about it since 2023.
Until the password is changed, the board now answers 403 to every API call except logging in, reading the access card, and changing the password, and the interface shows one page: the change. Not a warning banner — a banner is a thing people close.
The test is the factory password, not the first login. root's hash is
asked whether it still verifies the word turing, of /etc/shadow itself,
cached against that file's modification time. So a board whose password was
changed over SSH before anyone opened the interface is never asked, and a board
reset to factory defaults is asked again — which a flag saying "somebody has
been through the wizard" would get wrong in both directions.
What it deliberately does not cover: requests from the board's own loopback
interface, which are exempt. Refusing them would protect nothing — anyone with
a shell on the board is already root on it and can change the password
directly — while breaking the on-board tpi. The threat this is for is a
stranger who can reach port 443 on the management LAN, and that stranger is not
on loopback. tpi pointed at a factory board from another machine is over
the network, is refused, and says why.
It is also not the rest of the hardening: SSH still accepts that password until key-only SSH lands, and the loopback bypass above is its own fault, tracked separately.
Reconnect wrote a second copy of the scrollback
Section titled “Reconnect wrote a second copy of the scrollback”Affected every release up to BMC-UI 3.27.0; fixed in 3.28.0 (firmware v2.31.0). Pressing Reconnect kept the terminal, as it is meant to, and then replayed the daemon's whole 16 KiB ring buffer underneath what was already on screen — the same lines with the same kernel timestamps, twice:
[64064.315286] eth0: renamed from tmpe5b7c[65264.283498] eth0: renamed from tmp5cff0[61664.597477] eth0: renamed from tmpc8e55 <- the ring again, from the top[62864.338706] eth0: renamed from tmp83239It affected a board's own interface and the fleet alike, because one component serves both.
The replay is there because the daemon forwards only what arrives after a subscriber joins; without it, a console opened on a module that has been up for hours shows nothing at all. It simply never asked whether the terminal already held that output.
Clearing the terminal first would have fixed the duplication and cost the thing the scrollback is for. The daemon keeps only the last 16 KiB and one module boot is about 82 KB, so the terminal is the only place a full boot survives. Instead the replay now works out where what it has already shown ends inside the buffer it has just been handed, and writes only what follows: a reconnect with nothing new writes nothing, one after a gap writes exactly the gap, and when the module wrote more than the ring holds there is no overlap and the whole buffer is written, because there is a hole either way.
Redraw is unchanged and still clears first. It answers a different question: show me what the module's screen says now.
A console that failed at random, and a board that never said why
Section titled “A console that failed at random, and a board that never said why”Affected every release from bmcd 2.30.0 to 2.36.2; fixed in 2.36.3 (firmware v2.30.0). A serial console or an API call arriving through a proxy would occasionally fail outright, on any board, with nothing in the daemon's log and the board perfectly healthy either side of it. Reconnecting usually worked, which is what made it look like a network fault.
OpenSSL will not resume a TLS session on a server that asks for client
certificates unless the context carries a session id context — and the refusal
is not a quiet cache miss. It is internal_error, fatal, sent before a byte
of HTTP is exchanged:
error:0A000115:SSL routines:ssl_get_prev_session:session id context uninitializedThat error is raised on the server, which never logged it. The only trace anywhere was an alert the client could not explain.
It looked random because of who resumes. A proxy keeps one session per board and offers it on the next connection it opens, so connections taken from the pool were always fine and new ones were a coin flip. Measured on a gateway in front of two boards: 8 of 28 new connections failed to one, 19 of 45 to the other. Reproduced deterministically from the same host — 30 fresh connections all succeeded, 30 offering back a saved session all failed.
Nothing about it was specific to a gateway. Any client that resumes a session hit the same wall, and the fault arrived the day client certificates were first offered, so it was present and invisible for six releases.
The acceptor now sets a session id context, derived from the client CA so that replacing a board's trust anchor will not resume a session authenticated under the old one.
Tracked as SQU-212.
A module in flash mode looked exactly like dead hardware
Section titled “A module in flash mode looked exactly like dead hardware”Fixed in bmcd 2.36.3 (firmware v2.30.0), by making it visible rather than by
changing the behaviour. Flashing a module leaves the board's persisted USB
configuration at Flashing(nodeN, …), and the daemon re-applies it on every
start — which holds that module's USB-boot pin high and stops it booting from
its own eMMC.
The module carries on running, because it is already booted. The failure
arrives at its next reboot, which can be weeks later, and by then nothing
connects the two. What you see is a module that is silent on the serial
console — not a byte, not even a bootloader banner, because the loader does
not use the console — unreachable on the network, with the board still
reporting its rail on. tpi usb status did not help: it prints the same route
for a normal configuration and for this one.
Twenty minutes went into exactly that on 2026-09-12, on a board where the answer was sitting in the daemon's own database unexported.
/metrics now carries bmcd_node_usb_boot_armed, one sample per module.
Alert on it lasting more than a few minutes and the page reaches whoever armed
it while they still remember doing so; the
metrics reference has the rule. Finish a flash
with tpi usb device -n N and it never arms at all.
Tracked as SQU-213.
The board could stop checking for firmware, for ever
Section titled “The board could stop checking for firmware, for ever”Affected every release up to bmcd 2.34.0; fixed in 2.35.0. The Firmware page said checking the sources now and never stopped, with Check now disabled beside it, and the board could not have found a new release if one had appeared. Only restarting the daemon cleared it.
Opening the Firmware tab on a board whose cached listing had aged out was
enough to trigger it. bmc-2 sat in that state for three and a half hours
on 2026-09-11 — refreshing: true, the timestamp frozen, and no fan-out
process running at all:
{'age_seconds': 13004, 'checked_at': '2026-09-11T19:12:35Z', 'refreshing': True}# ps w — nothingThe claim that says "a refresh is running" was a flag taken before the work and released by a guard when it finished. That is correct for a crash and wrong for everything else: a task dropped before it starts constructs no guard, and a blocking call that never returns never drops one. Either way the flag stayed set and every later refresh returned early.
It is a deadline now, and a deadline cannot be lost: the claim expires whether or not anything is left to release it.
Worth knowing even now it is fixed, because the normal case is slower than it looks. A refresh asks four sources and takes between 75 and 230 seconds on this hardware, and the control is disabled for all of it.
Tracked as SQU-201.
The TLS certificate was an expired fossil
Section titled “The TLS certificate was an expired fossil”Fixed in v2.24.0 (SQU-115). /etc/ssl/certs/bmcd_cert.pem on the reference
board was issued June 2025 and expired July 2025. It was RSA 4096, had
no subject-alternative name — which no browser has accepted since 2017 — and
lives on the overlay, so it survived every firmware upgrade this fork had
shipped up to that point.
Three things were wrong at once, and all three are covered by a certificate that does not rot: the generation script now issues EC P-384 with real names and 825 days of validity, reissues 30 days before expiry rather than only when the file is missing, and refuses to touch a certificate it did not issue. Fifteen assertions cover it in CI.
Measured on both boards on 2026-09-11, after the fork's own certificates were replaced with ones from the estate's internal authority:
subject=CN=bmc-1.haarlem.lan issuer=CN=hive-internal-ca-p384notBefore=Sep 11 10:55:09 2026 GMT notAfter=Dec 10 10:55:09 2026 GMTP-384, named, and inside its validity on both. The board also publishes
bmcd_tls_certificate_expiry_timestamp_seconds, so the next expiry is
something a scrape notices rather than a person.
mDNS ate the board
Section titled “mDNS ate the board”Affected v2.9.0 through v2.12.0; fixed in v2.13.0. The mdnsd that
advertised turingpi.local leaked about 0.85 MB a minute and did not
stop. On a board with 116 MB of RAM that was fatal in roughly ninety minutes:
userspace stopped answering, the kernel kept replying to ping for a while, and
only cutting the power brought it back. It happened twice on 2026-09-09.
The rate followed mDNS traffic rather than time, so a quiet network hid it entirely and a busy one killed the board before lunch. That is why it read as intermittent.
The cause was the switch ports. Every DSA port on this board — node1
through node4, ge0, ge1, dsa — carries the same MAC address, and
mdnsd bound all of them. It saw its own advertisement arrive from what looked
like another host with its name, declared a conflict, and reloaded its
configuration: 825 times in twelve seconds, leaking on each one.
The fix is one line, binding it to the bridge instead:
MDNSD_ARGS="-i br0"Measured after: 0 reloads in 90 seconds and 8 kB of growth, against 956 kB/minute before. On an affected release, restarting the daemon is still a complete and instant remedy:
$ ssh root@<bmc> /etc/init.d/S50mdnsd restartMeasured on a board that had been up 36 minutes: available memory went from
54.4 MB back to 88.5 MB, and mdnsd from 36.0 MB back to 1.9 MB.
We introduced this. turingpi.local stopped resolving when avahi was dropped
for rootfs headroom, and mdnsd was chosen as the small replacement. We
compared the two on size alone. On a board with no swap and no watchdog, how a
long-running daemon behaves over hours deserved a look as well, and did not get
one.
Tracked as SQU-175, with the outage itself as SQU-172.
turingpi.local stopped resolving
Section titled “turingpi.local stopped resolving”Dropping avahi for rootfs headroom also removed the board's mDNS
advertisement, and nothing replaced it. Since tpi's default host is literally
turingpi.local, every tpi command without --host failed from v2.3.0
until v2.8.1 — including the one upstream's documentation tells you to run
first.
Fixed in v2.8.1 with mdnsd, which does the same job without the D-Bus,
expat and libdaemon that made avahi expensive. tpi 1.1.1 also says so
plainly when the name does not resolve, which matters on the older firmware
where it never will.
The command line did not work at all
Section titled “The command line did not work at all”Every command this fork added to tpi was broken from 1.1.0 to 1.2.0, and none
had ever been run against a board. The response unwrapper returned the API's
wrapper array instead of the result inside it; serde will build a struct from a
sequence by taking the elements as its fields in order, so the first thing every
command does — read about to check the daemon's version — failed with
invalid type: map, expected a string.
Behind that were four more: firmware check printed an empty version, thermal
printed raw JSON, every refusal printed as escaped JSON, and firmware install
had never worked in any release because its argument collided with the
--version flag.
All fixed by 1.2.2, each verified against a board. The examples on the command line page are now real output.
The firmware page froze
Section titled “The firmware page froze”Two causes. The daemon polled its four firmware sources one after another and held its cache lock for the whole 16 seconds, so a "check now" froze every other reader. And the interface's Check now button never sent the refresh parameter — it replayed the same request and got the daemon's half-hour cache back, which is to say the one control whose purpose was to bypass that cache was the only one that did not.
Fixed in bmcd 2.11.0 and BMC-UI 3.8.0. Measured after: 1 ms main-thread response while a check runs, with the list readable and the page navigable.
One failed request blanked the whole interface
Section titled “One failed request blanked the whole interface”The header's version panel is a suspense query mounted on every route, wrapped
in a bare <Suspense>. Suspense handles a promise that is pending; a
rejected one is thrown during render and passes straight through — so a single
failed about request unwound past the header, past the route and past the
root, none of which had a boundary.
Fixed in BMC-UI 3.8.0.