Skip to content

fix(bambu): stay alive when a printer does not answer the initial request - #29

Closed
jbp-kynze wants to merge 3 commits into
DMontgomery40:mainfrom
jbp-kynze:fix/bambu-command-timeout-crash
Closed

jbp-kynze wants to merge 3 commits into
DMontgomery40:mainfrom
jbp-kynze:fix/bambu-command-timeout-crash

Conversation

@jbp-kynze

@jbp-kynze jbp-kynze commented Sep 30, 2026 •

Copy link
Copy Markdown

Problem

Two Bambu Lab X1 Carbons (firmware 01.07, LAN Only Mode on) broadcast reports over MQTT but never answer bambu-node's initial information request. Effects:

  • After 5 s bambu-node's "Command execution timed out after 5 seconds." became an unhandled rejection. The rejection guard only knew three other errors, so Node exited (code 1) on the first get_printer_status. MCP clients saw this as a closed connection.
  • bambu-node resolves connect() only after that request is answered, so connect() hung, and with it every concurrent caller waiting on initialConnectionPromises.

Change

  • bambu-node-guard.ts: treat the command timeout as a known bambu-node internal error (same stack-origin check as the others).
  • bambu.ts: getPrinter stops waiting for the initial request 8 s after the MQTT session is up, stores that bounded promise so concurrent callers share it, evicts the client if connect() fails later, clears the grace timer, and disconnects on failure. getStatus returns the latest broadcast report and, when its own status request is unanswered, commandsAnswered: false plus a Developer Mode hint.
  • Tests for the crash and the guard, using a stub MQTT client. Changelog entry and patch bump to 1.2.11.

Evidence and limits

  • node --test tests/safety/bambu-node-guard.test.mjs: 5 pass (one new test reproduces the crash without the guard).
  • Read-only get_printer_status, three concurrent calls, against two real X1 Carbons: all return the broadcast state, no crash. No print, heating or motion command was sent. A plain get_version request also got no reply from either printer in 12 s, while broadcasts arrived.
  • Cause unknown. The printers run firmware 01.07, which predates Developer Mode. They broadcast full 70-field status reports about once a second and accept control commands (a chamber-light ledctrl toggled and restored on both, confirmed in the broadcast), but neither a get_version nor a pushall request produced any reply or echoed sequence id in 12-15 s.
  • On a Windows host, 6 tests in tests/behavior.test.mjs (and some Blender tests) fail identically on unmodified main (POSIX shell fixtures), so they are not caused by this change. The full suite was not run to completion here; CI on Linux is the gate.
  • The guard now ignores any unawaited bambu-node command timeout, not only the initial one; awaited commands still fail on their own timeout for their caller.
  • Publishing: the last two Publish Package runs on main (ci: npm trusted publishing (like bambu-printer-mcp); local code-review gate #26 and docs: CLAUDE.md pointer names the pre-PR review, not Codex #27) failed with E404 on PUT https://registry.npmjs.org/mcp-3d-printer-server, so npm still serves 1.2.9. The trusted publisher on npmjs.com probably needs to be set up for this repository and publish.yml (maintainer action). Separate from this PR.
  • bambu-printer-mcp needs the same fix; not ported here.

…uest

bambu-node sends a version request on connect and resolves connect() only
after it is answered. Two X1 Carbons in LAN Only Mode broadcast reports but
never answer it, so the 5 s command timeout became an unhandled rejection that
terminated the server, and connect() hung for every caller.

- Guard the command-timeout rejection like the other known bambu-node errors.
- Wait for the initial request only 8 s after the MQTT session is up, share
  that bounded wait between concurrent callers, and evict a failed or late
  client.
- get_printer_status reports commandsAnswered: false with a Developer Mode hint
  when its own status request is also unanswered.

Bump to 1.2.11.
@jbp-kynze jbp-kynze closed this Sep 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant