github maziggy/bambuddy v1.2.6b1-daily.20260818
Daily Beta Build v1.2.6b1-daily.20260818

pre-release3 hours ago

Note

This is a daily beta build (2026-08-18). It contains the latest fixes and improvements but may have undiscovered issues.

Docker users: Update by pulling the new image:

docker pull ghcr.io/maziggy/bambuddy:daily

or

docker pull maziggy/bambuddy:daily


**Tip:** Use [Watchtower](https://containrrr.dev/watchtower/) to automatically update when new daily builds are pushed.

Fixed

  • Archive metadata could describe a plate that was never printed — The layer height on the archive card and in the library's file details came only from the 3MF's project_settings.config, and the plate G-code beside it was read for the layer count alone — the first .gcode entry in the zip, whatever plate the archive was actually for. A multi-plate export therefore reported plate 1's layer count even when plate 3 ran, and nothing ever cross-checked the layer height against the plate that produced the print. Both now come from the printed plate: its G-code is read (64 KB, enough to reach the config block that carries layer_height 14–25 KB in, where 4 KB only ever reached the header), and its value wins over the project's where the two disagree. Source 3MFs, which carry no G-code, keep the project value exactly as before.
  • Slicing a file could ignore the process preset you picked — Bambuddy carries a designer's own process deviations across a re-slice (#2622) and pre-ticked all of them except the machine-coupled ones. layer_height is one that MakerWorld projects routinely carry, so picking "0.08mm High Quality" for a file whose designer had moved layer height to 0.2 sliced at 0.2 while the dropdown still read 0.08 — the same 0.2 the settings panel showed, tagged "from file". Layer height and first layer height are now treated like the machine-coupled keys: still offered, never pre-selected, and their badge in the settings panel names the conflict and shows the preset's own value beside the file's, so ticking one is a deliberate choice.
  • Statistics forgot the name of a printer that was deleted with its history kept (#2873, reported by rembomy) — Prints by Printer, the per-printer success breakdown, the time-accuracy list and Failures by Printer all resolved the name against the printers that exist right now, so deleting a printer and choosing to keep its prints turned "Ultron" into "Printer 1" everywhere. The runs themselves already recorded the name they printed on, and that is what those breakdowns fall back to now: the last name the id was known by, for as long as its prints are kept. A printer that still exists is named from its own record as before, so a rename shows up immediately rather than after the next print. Covered by backend and frontend regression tests.
  • Skip Objects went dead for the rest of a print if Bambuddy restarted while it was running — The object list lives in memory and is filled by the print-start path, which is deliberately suppressed on the first status push after a restart so the print is not archived twice. Everything else that moment restores — the archive, filament attribution, the timelapse baseline — came back; the object list did not, so the printer card saw zero objects and greyed out its Skip button. Measured on the maintainer's H2C: 8 objects loaded at 09:02, a restart at 09:17, and no way to skip anything for the remaining hour of the print. Nothing could recover it either, because the one endpoint that can rebuild the list is only reachable from the modal that the greyed-out button opens. The list is now restored on the way back up, from the archive of the print that is still running and matched on the job id the printer mints per print, so a stale archive cannot lend its objects to someone else's job. Two things behind it changed as well: rebuilding now reads the archived 3MF on disk before asking the printer for a file Bambuddy already has — that request was a full transfer off a machine mid-print, 15 MB in this case, and it cannot succeed at all on a printer that kept the file on internal storage — and the card now treats zero objects as "not loaded yet" rather than "nothing to skip", since a running print always has at least one. A single-object print still greys the button out, which is the case that rule was written for. The plate image in the modal came from the same place and had the same problem: the cover, the top view and the object-ID mask all re-fetched the 3MF from the printer after a restart, three fan-outs at once for one modal, so the picture arrived seconds after the list. They now read the running print's archived file too. Wiki updated. Covered by backend and frontend tests.
  • A print archived without its 3MF can be given its filament weight by hand (#1820, reported by ojimpo) — When the sliced file stays somewhere Bambuddy cannot read, the archive is created from the printer's report alone and carries no weight, so the print is missing from every filament total and there was no way to put it right afterwards: Rescan reads the figure out of the 3MF, and that archive has no file to read. The reporter's H2S print left 46 g of PLA on the spool with nothing recording it, and he corrected Spoolman by hand. Edit Archive now has a Filament used (g) field. It is written to the print's most recent run as well as to the archive, because the Projects roll-up and the Prometheus counter sum the runs rather than the cards — correcting only the card would have fixed the display and left every aggregate reading the old figure. The value is bounded at 0 to 100 kg, it is sent only when you actually change it, so an ordinary save cannot round off a sliced figure, and emptying the field clears it. A run that measured its own weight through spool tracking keeps that measurement — the correction fills in a run that has none, or one that only ever inherited the archive's estimate, and never overwrites a real measurement with a typed one. Nothing is deducted from Spoolman or internal inventory either: those are charged from what was tracked at the time, and a print that recorded nothing has nothing to reverse. On an archive that does have its 3MF, Rescan still overwrites what you typed — there the file is the authority. Translated in all locales; wiki updated. Covered by backend and frontend tests.
  • The internal-storage probe now logs which directory served the file (#1820) — When a printer says a print went to internal storage and Bambuddy finds it over FTPS anyway (#2856), the log said which file but not where it came from. On a printer that keeps uploads for weeks — the reporter's H2S has months of them in /cache — a reprint of a name that was re-sliced but never re-sent can match an older copy, and without the directory in the log that mismatch was invisible rather than merely rare. The download helper now reports the path that served the file instead of a bare success flag, and the hit line names it. Covered by backend tests.
  • Card and row actions were unreachable on phones and tablets (#2865, reported by aishlai) — The three-dot menu on a project card carries Edit and Delete and appeared only on hover, so on a phone there was no way to rename or delete a project at all; the File Manager's folder actions went the same way, as did duplicating a preset, renaming or deleting a tag, removing a print photo and deleting a plate-reference image. This is worse than a missing hover event: Tailwind v4 compiles hover: and group-hover: inside media (hover: hover), so on a touch-only device the rule that reveals the control is not merely never triggered, it is never applied — the element stays invisible for good. The hiding half is now what depends on a hover-capable pointer, so a device that cannot hover simply shows the control, and a mouse behaves exactly as before. Four spots on the Archives cards and two on the File Manager's file cards already tried to handle this by viewport width, under 768 pixels, which meant a phone was fine and a tablet in landscape was not; they now use the same capability check and the width guess is gone. Keyboard users were affected too, in the other direction — the buttons were invisible but still focusable, so tabbing through a card stopped on something nobody could see; focus now reveals them. Wiki updated. Covered by frontend tests.
  • The build plate of a powered-down printer can be cleared again (#2864, reported by bryanmahin) — With Auto Power Off enabled this is the ordinary end of every print: the job finishes, Bambuddy switches the printer off at the plug, and the plate is left flagged dirty on a machine that is no longer reachable. The operator then walks over, clears the plate, and had no way to say so — POST /printers/{id}/clear-plate answered 400 "Printer not connected", and the button was hidden on the printer card, so the physical clear-plate buttons some farms drive over the API went dead too. Everything gated on the flag stayed stuck until each printer was powered back on by hand, cleared, and switched off again, which is the opposite of what Auto Power Off is for. Nothing in clearing a plate talks to the printer: the flag is Bambuddy's own state, persisted in its database precisely so it survives the power cycle, and the check that refused was inherited from the stop, pause and resume handlers next to it, where reaching the printer genuinely is required. It is gone, and the card offers the control whether the printer is online or not — in both card sizes, and for bulk selections, where powered-down printers were being filtered out of a Clear All. This does not dispatch work to an unreachable machine: the queue still requires a live connection before it sends anything, and releasing the gate is what lets it power the printer back on for the next job instead of skipping it. One related gap went with it — a printer with no live connection at all, disconnected by hand or not yet reconnected after a restart, reported its plate as clean over the API regardless of what the database said, which hid the control on exactly the printers that needed it. Wiki updated. Covered by backend and frontend tests.
  • H2D archives lost their 3MF, thumbnail and filament data after the last update (#2856, reported by aishlai) — When a print starts, the printer says where it put the sliced file, and Bambuddy took brtc://emmc/<name> — internal storage — as proof there was nothing to fetch, so it archived the print by name alone. On an H2D with a card in the slot that is not true: the same file sits under /cache and downloads without complaint, as it had for that reporter's every print until the change landed. Bambuddy now checks instead of assuming. The printer names the exact file, so confirming it takes one connection across five paths rather than the ~110-connection search that made skipping worth doing — and when the file really is out of reach, as it is on an H2C or P2S with no copy on the card, the archive falls back exactly as before and still says why. The connection diagnostic asks the same question before warning that a print is out of reach. Covered by backend tests.
  • A printer with more than one smart plug never recorded energy or energy cost (#2859, reported by sn8key) — Linking a second plug to a printer — a dry box, a filter fan, a chamber light you want to switch from the printer card — stopped energy tracking on that printer completely, from the moment the second plug was linked. Per-print energy is the change in one plug's meter between the start and the end of a print, and both readings asked for "the plug on this printer" in a way that accepts one answer and fails on two. The failure was indistinguishable from having no plug at all: the print-end log said no starting reading had been taken, which is also what it says for a printer with nothing linked to it. Bambuddy now picks the printer's own plug — the one marked as supplying its power, and of those the one that actually reports a meter, so accessories drop out on their own — and names the plugs it tried when none of them measures anything. Linking several plugs to a printer is supported and always was; only energy assumed otherwise. Past prints cannot be recovered, since the starting reading was never taken. Covered by backend tests.
  • The smart plug page counted an online plug as offline unless it reported energy (#2859) — A plug with no power sensor is still online, but "N/M plugs online" only counted the ones sending energy figures, so a working switch showed as offline for as long as it stayed linked. The count now reflects whether the plug answers.
  • Reprints of a file already on the printer archived without their thumbnail or filament data (#2780 regression) — Printing a file that is already on the printer — from the printer's own screen, from Handy, or after sending it to storage from a slicer and pressing print — reports the file by its path rather than by how it got there. Bambuddy read anything that was not a fresh upload as "the printer kept this on internal storage", stopped looking, and archived the print with only its name and timing. The file was on the card the whole time: on the machine this was measured on, /media/usb0/foobar.gcode.3mf was listable and downloadable over FTP at the moment Bambuddy decided it was unreachable. This affected every model, not only the H2 series and P2S the original change was about, and it arrived with that change on 2026-08-14 — before it, those prints archived normally. Bambuddy now reads the path: the printer's own internal model cache is still skipped, since nothing there is reachable, and everything else is looked for as it always was. Covered by backend tests.
  • Prints sent from a slicer were sometimes logged as though Bambuddy had sent them (#2843 follow-up) — Bambuddy records the dispatch behind every print so a support bundle shows where the sliced file went, and it told its own dispatches apart from a slicer's by a sequence number it believed was unique to it. It is not: that number is the slicer convention Bambuddy adopted, and measured on the wire OrcaSlicer counts from it while Bambu Studio counts from the same base a few higher. Whichever dispatch happened to land on the shared value was filed as Bambuddy's own and never recorded — after a slicer restart, that is the first print you send. Bambuddy now recognises its own dispatch by the job it actually sent. Nothing about printing or archiving changed; the entry was diagnostic, but it is the entry that tells you whether a printer stores your files somewhere Bambuddy can read them. Covered by backend tests.
  • A print with no 3MF could take its filament figures from an unrelated model (#2843, reported by gyrene2083) — Bambu Studio sends a sliced file to the printer's internal storage on H2-series and P2S, which Bambuddy cannot read, so those prints archive without a 3MF (BambuStudio#10481 tracks that default upstream). Bambuddy then looks for the same model in your Library or among earlier prints, which is how a reprint still gets its filament accounted for. The name it searched on was the wrong one. A running print reports the file it is executing — always Metadata/plate_1.gcode — and with no 3MF to correct it, that path became the archive's name and plate_1 became the search term. Every Bambu print has a plate 1, so the search matched on nothing meaningful and took whatever came back: on the maintainer's H2D a 1.6 g Cube was costed from a 207 g four-colour ABS print whose file happened to be named lid_plate_1.3mf. The match now uses the model name the printer reports alongside the plate path, a plate name on its own is refused rather than searched for, and a name must match a whole filename instead of merely appearing inside one. A print that cannot be identified is left untracked, which is the honest answer — the previous behaviour was to charge your spools for a model you did not print. Covered by backend tests, including the exact collision measured on the H2D.
  • Timelapses were lost, and written outside the data directory, for any print archived without a 3MF (#2843) — Every H2-series and P2S print sent from Bambu Studio, so not a rare case. The video downloaded from the printer correctly and was then written next to the data directory rather than inside it, because an archive with no 3MF has no directory of its own and the destination was derived from the missing file's path. In Docker that meant a permission error, retried and discarded twenty-five times over twelve minutes, roughly a hundred connections to the printer for a video that was thrown away each round. Where that location happened to be writable it was worse: the file landed beside the installation, the attach failed anyway, and the stray video stayed there. Bambuddy has had a shared helper for exactly this since #1820 and this was the one place still deriving the path by hand. Timelapses now land in the archive's own folder and attach normally. Covered by backend tests.
  • A slot that could not be charged now says so (#2843) — When a print's filament cannot be read from a 3MF, Bambuddy falls back to the drop in the AMS's own remaining-filament percentage. That needs a reading when the print starts, and a spool without RFID has none until you set a remaining amount by hand — so those slots were skipped in silence. Nothing was deducted and nothing said why, which is indistinguishable from having nothing to deduct. Every other reason for skipping a slot was already logged; this one now is too.
  • PostgreSQL installs on a non-UTC timezone showed AMS History and Archive timestamps hours in the future (#2855, reported by Tolga-Unal) — On UTC+3 every AMS humidity reading and every archive was stamped three hours ahead of when it happened. Bambuddy stores timestamps without an offset and treats them as UTC everywhere, and the Python side has done so since #504 — but around a hundred and fifty timestamps are not written by Bambuddy at all. They are database defaults, filled in by the database, and PostgreSQL fills them from a clock whose timezone is the server's own. A Postgres container started with TZ=Europe/Istanbul bakes that zone in when the cluster is created, so those columns received local wall-clock while everything reading them assumed UTC, and the display added the offset a second time. Bambuddy's connections now pin their session to UTC, so what the database writes matches what the rest of the product means, whatever the server is set to. SQLite was never affected — its clock is UTC by definition, which is why this hid for as long as it did, and the fix makes Postgres agree with SQLite rather than inventing a third convention. Timestamps already recorded are not rewritten: which of them were written by the database and which by Bambuddy cannot be told apart after the fact, and an install that started on SQLite holds both kinds. Everything from the upgrade forward is correct; older rows keep the times they were given. One related mismatch went with it — the support package's "oldest pending queue item" age subtracted a local clock from a UTC column, reporting a job queued five minutes ago as three hours old east of Greenwich and a negative age west of it. Covered by backend tests, including one that reproduces the reporter's three-hour shift.
  • K-profiles follow an AMS when it moves between Filament Track Switch inlets — K-profiles are calibrated per nozzle, and the printer numbers its calibration table per nozzle too, so entry 16 exists on both hotends and means a different profile on each. An AMS tray, however, holds exactly one index. Move an AMS to the switch's other inlet and every configured slot in it silently keeps pointing at the old hotend's table: on the maintainer's H2C a black PLA calibrated 0.018 on the left and 0.020 on the right stayed on the left profile after the move, and a manual RFID re-read only re-asserted the same wrong one. Bambuddy already stores both profiles for a spool, so the move now re-selects the counterpart for the nozzle that AMS actually feeds. Only the calibration binding changes and only for slots whose spool already has a profile for the new nozzle — configuring a slot is a deliberate preparation step, so a slot Bambuddy knows nothing about, or a spool calibrated on one hotend only, is left exactly as you set it. Nothing is re-applied on the first sighting of a binding either, or every reconnect would overwrite a choice made by hand.
  • Configure Slot picks the K-profile for the slot's own nozzle — The profile dropdown identified an entry by name and K value alone, with nothing naming the hotend, so a filament calibrated on both appeared twice with no way to tell them apart, and two that happened to share a K value collapsed into whichever the printer listed first. The tie-break meant to prefer the slot's own nozzle was gated on a value that is never set on a machine with a Filament Track Switch, where no AMS reports a nozzle at all — so the pick was arbitrary, and the fallback for an unrecognised binding was simply the first profile in the list. Options now carry the hotend, matches are scoped to the nozzle the slot actually feeds (the other hotend's profiles remain available under Other K profiles), and the slot's active index is resolved against its own nozzle rather than followed into the wrong table. The K value shown per slot on the printer card was affected by the same confusion and is now resolved the same way. Covered by backend and frontend tests.
  • Auto K-profile calibration no longer leaves an archive behind — When flow dynamics calibration is on, the printer lays down a pressure-advance line before the print itself. It announces that over MQTT through the same print-start event a real print uses, so Bambuddy archived it: a row named auto_pa_line_calib_mode, marked as having no 3MF, in among your actual prints, plus a "Print started" and a "Print completed" notification for each one. Bambuddy has always skipped the printer's other internal jobs, but only by spotting the /usr/ path they carry — and this one arrives as a bare subtask name with no path at all, so it went straight past. It is now recognised by name, from either field the printer might report it in, and matched exactly so that a file you have deliberately named after the calibration is still your file. The completion is quiet too, which matters more than the noise: with no archive to close, it would have fallen into the path that attributes an unmatched completion to any job the printer finished in the last five minutes — and a calibration that runs alongside a real print would have told that print's owner it was done, early. Skipping the run early also saves the pointless FTP sweep for a 3MF that cannot exist, roughly a hundred connections to a printer that is mid-calibration. Covered by backend tests.
  • A printer being busy or offline no longer blocks printing from its card (#2849) — Dragging a sliced file onto a printer card refused the drop unless the printer was connected and neither printing nor paused, showing a red "Printer busy" and discarding the file; the card's Print button disappeared under the same condition. The workaround was to upload to the File Manager and queue it from there by hand, which is the same thing with more steps. It was never a real restriction: every print Bambuddy sends becomes a queue item, and dropping onto an idle printer only looks instant because the scheduler dispatches it right away. Both routes now work whatever the printer is doing, and a busy one simply queues the job. Offline printers are included, so you can queue work for a machine that is powered down and have it dispatch when it reconnects. The overlay says which you are getting — "Drop to print" when the job would start immediately, "Drop to queue" when it would wait, covering a print in progress, a paused job, an AMS mid-drying and a plate not yet cleared. That wording comes from the same check the Print Modal uses for its own "will start later" notice, so the card and the modal cannot disagree. The drop is also now gated on the permissions the flow actually uses, Library Upload and Queue Create, matching the Print button beside it; it previously checked Printer Control, which meant someone holding that but neither of the others got the file uploaded and then rejected by the queue, leaving it stranded in the library. Translated in all locales; wiki updated. Covered by frontend tests.
  • Drying an AMS no longer sends an hourly "temperature high" alert for the whole cycle (#1802) — The AMS temperature alert compares against the same threshold that colours the printer card, which defaults to 35 C, while drying deliberately runs at 45 C for PLA, 65 C for PETG and up to 85 C on an AMS-HT. The alert repeats once an hour for as long as the condition holds, so a twelve-hour dry sent twelve notifications about a temperature you asked for, and then kept sending them while the unit cooled back down. The alert is now held back for the length of a cycle and through the cool-down that follows it, using the drying state the firmware already reports rather than anything you have to configure. Suppression lifts as soon as the unit reads back at or below your threshold, so a 65 C cycle in a cold basement and a 45 C one in a warm room each get exactly the cool-down they need instead of a fixed guess. Two things are deliberately left alone: the humidity alert, which is the one you want during drying because the number falling is the point, and a unit reporting HeatOutOfControl, where an AMS that has lost thermal control is precisely when the alert should still reach you. Because a cycle plus its cool-down can outlast a restart, the suppression is stored rather than held in memory. No new setting — the alert simply stops firing for heat you asked for. Wiki updated. Covered by backend tests.
  • Closing the bug-report panel no longer throws the capture away and leaves the logs running (#2847) — Step 2 of the report flow asks you to reproduce the problem, and the panel sits over the part of the app you have to reach to do it. Closing it was the obvious move and it was the wrong one twice over. Reopening put you back on an empty step 1 — while the server was still logging at DEBUG, with nothing left in the flow that could stop it, because only Stop & Submit ever did. Leave it closed instead and the five-minute cap eventually fired behind your back: logging stopped and the report was filed with no window open and no confirmation that it had happened. Which of the two you got depended only on whether you reopened the panel inside five minutes. A capture is now a thing that outlives the panel. Closing keeps it running and says so — the bug button turns amber for as long as a capture is going, and clicking it returns you to step 2 with your description, your screenshot and the elapsed timer where you left them. If the cap does fire while the panel is closed, the panel reopens so the submission happens in front of you rather than behind you. The timer is measured against the capture's start time rather than counted in ticks, so a background tab, where browsers throttle timers hard, no longer stretches five minutes into something else. A capture also survives a page reload, which matters because reloading is a perfectly ordinary step in reproducing a bug: the report picks it back up where it was. One that outlived the cap while nobody was watching is not resumed and not filed — a description written an hour ago is not a report you are still expecting — but the log level is put back, which is the part that previously stayed wrong indefinitely. Translated in all locales; wiki updated. Covered by frontend tests.
  • The File Manager's card menu no longer loses its top entry (#2846) — In grid view a file card's action menu was drawn inside the card, and the card clipped anything its children painted outside it. A card is as tall as its square thumbnail plus whatever metadata the file has, so an STL — which has none beyond a name and a size — produced the shortest card in the library, about 270px against a seven-entry menu that needs closer to 310px. The difference was one row, and the row it took was the top one: Slice, since Print is only offered for a file that is already sliced. A 3MF carries a target model and a print count, two more rows, and its card was tall enough, which is why the button appeared there and looked like a file-type rule rather than a layout accident. Nothing about STL was special; the shortest card simply lost the first item, whichever it happened to be. The menu now opens against the viewport, the way the archive card's menu already did, so no card can crop it, and the card no longer clips its own children. List view was never affected — it has no menu, only inline buttons. Covered by a frontend test.

Don't miss a new bambuddy release

NewReleases is sending notifications on new releases.