Bambu Studio Version
2.6.1.55
Where is the application from?
Bambu Lab GitHub releases
OS version
macOS 26.4.1 (25E253)
Additional system information
This bug can replicate on all system
Printer
All printer
How to reproduce
- Create a new filament preset (e.g., based on Generic PETG).
- Change only the Standard nozzle temperature (e.g., set to 270°C).
- Leave the High Flow nozzle temperature untouched / at default.
- Export the filament preset via File → Export → Export Presets.
- Import the exported preset via File → Import → Import Presets.
- In the printer settings, select the High Flow nozzle.
- Slice any model and check the temperature settings or generated G-code.
Actual results
The imported preset JSON contains:
"nozzle_temperature": [
"270",
"nil"
],
"nozzle_temperature_initial_layer": [
"270",
"nil"
]
When the High Flow nozzle is selected, BambuStudio deserializes "nil" into INT_MAX (2147483647). This propagates into the slicer UI and G-code:
The UI displays this as approximately 1500°C (or the firmware's max cap), which is physically impossible and potentially harmful.
Expected results
After import, the High Flow nozzle temperature should fall back to the inherited/default value (e.g., 250°C or whatever the parent preset defines). It should not become an extreme invalid value.
Project file & Debug log uploads
additional information:
Root Cause (from code inspection)
Export writes "nil": Preset::save() uses set_with_nil() to serialize unset variant slots as the literal string "nil" to preserve diff/inheritance state.
Import maps "nil" to sentinel: ConfigOptionIntsNullable::deserialize() converts "nil" → std::numeric_limits::max() (2147483647).
No fallback: get_at() returns the sentinel directly for valid indices without checking is_nil(). Most G-code temperature consumers only check temp > 0, which INT_MAX passes.
Critical mismatch — Import vs. Restart paths:
Right after import (PresetBundle::import_json_presets()):
Uses new_config.apply(std::move(config)) which blindly copies the child preset's nil sentinel into memory via set(). The High Flow slot becomes INT_MAX/NaN in the active config.
After restart (PresetCollection::load_presets()):
Rebuilds the preset from parent config first, then
calls update_diff_values_to_child_config() → set_only_diff(). This only copies child slots where !is_nil(...), so nil slots are skipped and the parent's concrete value remains in memory. This masks the bug in the UI, but the JSON file on disk still contains "nil" — so any fresh import re-triggers the corruption.
This path mismatch is why the bug appears immediately after import but seems "fixed" after restarting BambuStudio.
Archive.zip
Checklist of files to include
Bambu Studio Version
2.6.1.55
Where is the application from?
Bambu Lab GitHub releases
OS version
macOS 26.4.1 (25E253)
Additional system information
This bug can replicate on all system
Printer
All printer
How to reproduce
Actual results
The imported preset JSON contains:
When the High Flow nozzle is selected, BambuStudio deserializes "nil" into INT_MAX (2147483647). This propagates into the slicer UI and G-code:
The UI displays this as approximately 1500°C (or the firmware's max cap), which is physically impossible and potentially harmful.
Expected results
After import, the High Flow nozzle temperature should fall back to the inherited/default value (e.g., 250°C or whatever the parent preset defines). It should not become an extreme invalid value.
Project file & Debug log uploads
additional information:
Root Cause (from code inspection)
Export writes "nil": Preset::save() uses set_with_nil() to serialize unset variant slots as the literal string "nil" to preserve diff/inheritance state.
Import maps "nil" to sentinel: ConfigOptionIntsNullable::deserialize() converts "nil" → std::numeric_limits::max() (2147483647).
No fallback: get_at() returns the sentinel directly for valid indices without checking is_nil(). Most G-code temperature consumers only check temp > 0, which INT_MAX passes.
Critical mismatch — Import vs. Restart paths:
Right after import (PresetBundle::import_json_presets()):
Uses new_config.apply(std::move(config)) which blindly copies the child preset's nil sentinel into memory via set(). The High Flow slot becomes INT_MAX/NaN in the active config.
After restart (PresetCollection::load_presets()):
Rebuilds the preset from parent config first, then
calls update_diff_values_to_child_config() → set_only_diff(). This only copies child slots where !is_nil(...), so nil slots are skipped and the parent's concrete value remains in memory. This masks the bug in the UI, but the JSON file on disk still contains "nil" — so any fresh import re-triggers the corruption.
This path mismatch is why the bug appears immediately after import but seems "fixed" after restarting BambuStudio.
Archive.zip
Checklist of files to include