Question: server/files/metadata reflects live state #102

Open
opened 2026-07-24 21:38:43 +02:00 by fmontagna · 1 comment

While using a Moonraker client (moonraker-obico) I noticed a few things around server/files/metadata that seem to come from the endpoint being built from live print state rather than from the file. Wanted to ask whether these are intended before assuming they're bugs.

Note: I start prints directly from Anycubic Slicer Next, not through the bridge, so the file is not in the bridge's GCode store (/kx/files is empty). Some of the points below may be related to that.

1. filename parameter is ignored

Any query returns the running job's metadata, even for a non-existent file:

curl -s "http://BRIDGE:7125/server/files/metadata?filename=DOES_NOT_EXIST.gcode"

returns metadata for the currently printing file. Also on this endpoint, size is 1 for files not in the store and estimated_time is null, though both seem available from buried/report (gcode_size, estimate_duration).

Also on this endpoint, some fields look like they could be populated from data that already arrives in buried/report but aren't:

  • size is 1 for files not in the store — buried/report carries the real gcode_size
  • estimated_time is nullburied/report carries estimate_duration

Is querying arbitrary files out of scope, or should it look the file up in the store?

2. total_layers / curr_layer not reset at end of print

_on_print resets several fields on stoped/canceled but not total_layers/curr_layer; finished resets only file_ready. So after a print finishes, querying the metadata still returns the previous job's values until a new buried/report arrives.

At the start of the next print there's a window (print/report without layer keys, before buried/report) where the endpoint serves the previous job's layer count / object height. Is this expected?

3. progress non-monotonic during pre-print phases

During checking/auto_leveling/preheating the printer reports a progress that tracks the prep phase and resets to 0 when printing starts. It's forwarded to virtual_sdcard.progress / display_status.progress, which in Moonraker is usually treated as monotonic (fraction of file printed).

(Mapping preheating -> printing itself seems fine / matches Klipper, just asking about the progress value.)

While using a Moonraker client (moonraker-obico) I noticed a few things around `server/files/metadata` that seem to come from the endpoint being built from live print state rather than from the file. Wanted to ask whether these are intended before assuming they're bugs. Note: I start prints directly from Anycubic Slicer Next, not through the bridge, so the file is not in the bridge's GCode store (/kx/files is empty). Some of the points below may be related to that. ## 1. `filename` parameter is ignored Any query returns the running job's metadata, even for a non-existent file: ``` curl -s "http://BRIDGE:7125/server/files/metadata?filename=DOES_NOT_EXIST.gcode" ``` returns metadata for the currently printing file. Also on this endpoint, `size` is `1` for files not in the store and `estimated_time` is `null`, though both seem available from `buried/report` (`gcode_size`, `estimate_duration`). Also on this endpoint, some fields look like they could be populated from data that already arrives in `buried/report` but aren't: - `size` is `1` for files not in the store — `buried/report` carries the real `gcode_size` - `estimated_time` is `null` — `buried/report` carries `estimate_duration` Is querying arbitrary files out of scope, or should it look the file up in the store? ## 2. `total_layers` / `curr_layer` not reset at end of print `_on_print` resets several fields on `stoped`/`canceled` but not `total_layers`/`curr_layer`; `finished` resets only `file_ready`. So after a print finishes, querying the metadata still returns the previous job's values until a new `buried/report` arrives. At the start of the next print there's a window (`print/report` without layer keys, before `buried/report`) where the endpoint serves the previous job's layer count / object height. Is this expected? ## 3. `progress` non-monotonic during pre-print phases During `checking`/`auto_leveling`/`preheating` the printer reports a `progress` that tracks the prep phase and resets to 0 when printing starts. It's forwarded to `virtual_sdcard.progress` / `display_status.progress`, which in Moonraker is usually treated as monotonic (fraction of file printed). (Mapping `preheating` -> `printing` itself seems fine / matches Klipper, just asking about the progress value.)
fmontagna added the
enhancement
label 2026-07-24 21:38:43 +02:00
Owner

Thanks for the precise writeup, @fmontagna — genuinely useful to get "is this intended?" framed this clearly instead of a vague bug report. Went through all three carefully:

1. filename parameter — you're right that something's off here, though I want to correct the framing slightly: the parameter isn't ignored outright, _build_file_metadata() does look up the requested file's own row in the GCode store. The actual bug is more subtle: layer_height/total_layers/estimated_time were read from live in-memory state first, and only fell back to the queried file's own stored row when the live value happened to be falsy. So querying metadata for any file other than the currently/last-tracked job could leak that job's layer count / estimated time into the response. Fixed — live state is now only consulted when the query targets that same tracked file; any other filename (including a nonexistent one) relies solely on its own record.

On size/estimated_time specifically: I couldn't find any buried/report MQTT topic, gcode_size, or estimate_duration field anywhere in this bridge's code or MQTT subscriptions (the topics we subscribe to are tempature/report, print/report, info/report, file/report, multiColorBox/report, light/report, skip/report). Could you say more about where you observed buried/report? If it's from raw MQTT sniffing on a different firmware version, or from something moonraker-obico surfaces internally, that'd help me figure out whether it's something we should be subscribing to as well. The size: 1 fallback (gf.get("size_bytes") or 1) for files without a store entry is a real, separate rough edge that I'd like to fix regardless — it's just not clear yet what a reliable live-value source for it would be without a print sliced/uploaded through the bridge.

2. total_layers/curr_layer not reset — confirmed, and it turned out to be worse than just those two fields: a successful finish (state=finished) only ever cleared file_ready, while stop/cancel correctly reset progress, filename, duration, and everything else. So after a normal completed print, the metadata endpoint (and other stale fields) could keep serving the just-finished job's data indefinitely, not just its layer count. Both _on_print and _on_info now do a full reset (including layer fields) on all three terminal states (finished/stoped/canceled).

3. Non-monotonic progress during pre-print phases — confirmed. preheating/auto_leveling/checking/updated/init all map to Klipper's printing state for compatibility, but the printer's own progress value during those phases was passed straight through to virtual_sdcard.progress/display_status.progress. That value no longer gets forwarded during those phases — real print progress only starts flowing once the printer reports printing.

All three fixes committed locally on nightly with a dedicated test suite, going out with the next nightly build — still hoping to hear back on the buried/report question above before I take a swing at the size fallback.

Thanks for the precise writeup, @fmontagna — genuinely useful to get "is this intended?" framed this clearly instead of a vague bug report. Went through all three carefully: **1. `filename` parameter** — you're right that something's off here, though I want to correct the framing slightly: the parameter isn't ignored outright, `_build_file_metadata()` does look up the requested file's own row in the GCode store. The actual bug is more subtle: `layer_height`/`total_layers`/`estimated_time` were read from live in-memory state *first*, and only fell back to the queried file's own stored row when the live value happened to be falsy. So querying metadata for any file other than the currently/last-tracked job could leak that job's layer count / estimated time into the response. Fixed — live state is now only consulted when the query targets that same tracked file; any other filename (including a nonexistent one) relies solely on its own record. On `size`/`estimated_time` specifically: I couldn't find any `buried/report` MQTT topic, `gcode_size`, or `estimate_duration` field anywhere in this bridge's code or MQTT subscriptions (the topics we subscribe to are `tempature/report`, `print/report`, `info/report`, `file/report`, `multiColorBox/report`, `light/report`, `skip/report`). Could you say more about where you observed `buried/report`? If it's from raw MQTT sniffing on a different firmware version, or from something moonraker-obico surfaces internally, that'd help me figure out whether it's something we should be subscribing to as well. The `size: 1` fallback (`gf.get("size_bytes") or 1`) for files without a store entry is a real, separate rough edge that I'd like to fix regardless — it's just not clear yet what a *reliable* live-value source for it would be without a print sliced/uploaded through the bridge. **2. `total_layers`/`curr_layer` not reset** — confirmed, and it turned out to be worse than just those two fields: a *successful* finish (`state=finished`) only ever cleared `file_ready`, while stop/cancel correctly reset progress, filename, duration, and everything else. So after a normal completed print, the metadata endpoint (and other stale fields) could keep serving the just-finished job's data indefinitely, not just its layer count. Both `_on_print` and `_on_info` now do a full reset (including layer fields) on all three terminal states (`finished`/`stoped`/`canceled`). **3. Non-monotonic progress during pre-print phases** — confirmed. `preheating`/`auto_leveling`/`checking`/`updated`/`init` all map to Klipper's `printing` state for compatibility, but the printer's own progress value during those phases was passed straight through to `virtual_sdcard.progress`/`display_status.progress`. That value no longer gets forwarded during those phases — real print progress only starts flowing once the printer reports `printing`. All three fixes committed locally on `nightly` with a dedicated test suite, going out with the next nightly build — still hoping to hear back on the `buried/report` question above before I take a swing at the `size` fallback.
Sign in to join this conversation.
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: viewit/KX-Bridge-Release#102
No description provided.