From 537317b26ff24a4e7bf27189911f8e4d25f99d69 Mon Sep 17 00:00:00 2001 From: Petru Conduraru Date: Mon, 13 Jul 2026 06:38:01 +0300 Subject: [PATCH] Fix ci-bonsai-daily: guard on_depsgraph_update_caps during file load on_depsgraph_update and on_depsgraph_update_caps are registered together as persistent depsgraph handlers (bim/module/clip_box/__init__.py:50-52). on_depsgraph_update guards with `if cls._file_loading: return`, but the sibling on_depsgraph_update_caps did not, so a depsgraph tick during the file-load window still ran it. Beyond the failing test, this can re-arm a cap-rebuild bpy.app.timers callback in the exact load window _on_load_pre cancels timers for, against regions whose GPU state is not yet wired. Add the same _file_loading guard as the first check. Verified in headless Blender: test_clip_box.py::TestRefreshTimerLifecycle::test_depsgraph_update_no_op_while_loading 1 failed -> passed. This change was made with the assistance of an AI tool. Co-Authored-By: Claude Fable 5 --- src/bonsai/bonsai/tool/clip_box.py | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/bonsai/bonsai/tool/clip_box.py b/src/bonsai/bonsai/tool/clip_box.py index 5ac320e423..14f81d4e04 100644 --- a/src/bonsai/bonsai/tool/clip_box.py +++ b/src/bonsai/bonsai/tool/clip_box.py @@ -1270,6 +1270,17 @@ class ClipBox: def on_depsgraph_update_caps(cls, scene, depsgraph) -> None: """Depsgraph entry-point — guard, then delegate to the modal-aware debounce in :meth:`_handle_cap_tick`.""" + # Same file-load danger window as on_depsgraph_update: a real + # depsgraph tick during load (between load_pre and the new file's + # first paint) must not re-arm a cap-rebuild timer. _on_load_pre + # already cancels any in-flight timer via _cancel_pending_cap_rebuild; + # without this gate, a depsgraph_update_post event firing later in + # the same load (Blender fires these while building the new file's + # scene) would immediately reschedule one via _handle_cap_tick, + # undoing that cancellation and re-arming against regions whose GPU + # state is not yet wired. + if cls._file_loading: + return if getattr(bpy.context, "screen", None) is None: return if cls._active_scene_props(scene) is None: