Bonsai: fix Link IFC silently failing to build its cache - #9360
Draft
BIMvoice wants to merge 1 commit into
Draft
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linking an IFC can silently do nothing: no geometry appears, no error is shown, and the operator still reports success. Reported by a user who noticed that a cache file older versions created was no longer being written.
Root cause
LoadLink.link_ifc()spawns a headless Blender subprocess to build the.ifc.cache.blendthat linking then loads. That subprocess is started with:--addonsregisters the addon's classes but does not populatebpy.context.preferences.addons. So in the child process, anything that reads addon preferences raises:The child dies, the
.blendis never written, and linking has nothing to load.The path into that call is
load_pset_templates->get_user_data_dir(tool/blender.py:2148) ->get_addon_preferences().Why it is version dependent
That
get_user_data_dircall arrived withc91fbc4d40"Setup user data dir" (2025-01-21). Bonsai before that commit never touched addon preferences in the child, so the cache was written and linking worked. Afterwards it can fail. That matches the report of "older versions created this file, newer ones do not" precisely.It does not fail for everyone, which is why it has been hard to pin down. It needs the addon to be enabled in the current session but not yet persisted to saved preferences: a fresh enable, a first install, or a new profile. Once preferences have been saved, the key exists and the child survives.
The silent part, which is arguably the worse bug
A
printto a console most users never open, and noself.report().subprocess.runalso did not capture output, so the child's traceback, which names the real cause, was discarded. The user sees a click that does nothing.Changes
Enable the addon properly in the subprocess.
addon_utils.enable(name, default_set=True, persistent=False)inside the generated script, so preferences exist for it to read.persistent=Falseso nothing is written to the user's saved preferences.Check the cache directory is writable before spawning, with a message that names the likely culprits:
The cache still lives next to the IFC. That behaviour is unchanged, since other code and users depend on it.
Use
{value!r}instead of"{value}"throughout the generated script. Paths and property values were interpolated into string literals, so a quote, a trailing backslash or awkward characters could produce a syntactically broken script.repr()always yields a valid escaped literal.Removed
h5_filepath. Declared at line 1579 and never read anywhere in the tree. It is already gone onv0.9.0.Verification
Reproduced live in Blender 5.2 with an isolated profile and a real headless subprocess, not a simulation.
Before, with the cache directory set read-only:
Nothing reported, operator claims success.
After, same conditions:
And in a writable directory after the fix: subprocess returns 0,
.ifc.cache.blendand.ifc.cache.jsonare written, operator finishes.black and ruff clean.
Scope honesty
No automated test. Exercising this needs a real headless Blender subprocess with the full dependency set, which is not currently wired up for this module. Verification is the manual reproduction above, so nothing guards against regression in CI. If maintainers would like a test, guidance on the preferred harness would be welcome.
Left deliberately unchanged:
LinkIfc._execute()callsbpy.ops.bim.load_link(...)and discards the result, so the outer operator reportsFINISHEDeven when the nested one fails. The error message still surfaces, so this does not block the fix, but the top-level status does not reflect partial failure in a multi-file batch. That felt like a separate change with its own risk, so it is flagged rather than bundled.Produced with AI assistance.