Hi McNeel team, after a significant debugging session on some of our internal code, I seem to have find a really specifically odd bug. I have had Claude narrow it down through the MCP-link and have also tested the observations myself and can confirm the unexpected behaviour. Please find Claudes formal report below:**
Rhino version:** 8.32.26160.13001
OS: Windows 11
Script engine: Rhino’s built-in Python 3 (CPython 3.9.10) via the ScriptEditor
Summary
Calling rhinoscriptsyntax.AddAlias() or rhinoscriptsyntax.DeleteAlias(), either one alone, no other change needed, appears to silently reset Rhino.Display.DisplayModeDescription’s list back to some earlier/stale in-memory or on-disk state. A display mode created after that state was captured disappears entirely, without ever being deleted.
The tricky part: this is not visible within the same script execution. GetDisplayModes() continues to report correctly right after the alias call, and even later in the same script. The reset only becomes visible the next time anything queries display modes in a separate execution, the next script run, or opening Options > Display Modes.
I ran into this while debugging why a company-wide “enforce our custom display modes” setup script kept intermittently losing its changes between runs, with no code difference and no user action in between. Once isolated, it reproduces reliably and is not specific to our codebase a two-line, unrelated alias add+remove is seemingly enough to trigger it.
Steps to reproduce
Run these as two separate script executions (e.g. two separate -ScriptEditor Run calls, or paste into the editor and run, close, reopen, run again, not two functions called back to back in one script,the bug will not show up that way).
Step 1:
import Rhino
import rhinoscriptsyntax as rs
PROBE_NAME = "ZZZ_REPRO_PROBE"
ALIAS_NAME = "ZZZ_REPRO_ALIAS"
existing = Rhino.Display.DisplayModeDescription.FindByName(PROBE_NAME)
if existing:
Rhino.Display.DisplayModeDescription.DeleteDisplayMode(existing.Id)
shaded = Rhino.Display.DisplayModeDescription.FindByName("Shaded")
probe_id = Rhino.Display.DisplayModeDescription.CopyDisplayMode(shaded.Id, PROBE_NAME)
print("Created probe:", probe_id)
print("Present now:", Rhino.Display.DisplayModeDescription.FindByName(PROBE_NAME) is not None)
# the only other thing this script does - nothing here touches display modes
rs.AddAlias(ALIAS_NAME, "_Line")
rs.DeleteAlias(ALIAS_NAME)
print("Present at end of THIS script:", Rhino.Display.DisplayModeDescription.FindByName(PROBE_NAME) is not None)
Output:
Created probe: <guid>
Present now: True
Present at end of THIS script: True
Step 2 (separate run):
import Rhino
PROBE_NAME = "ZZZ_REPRO_PROBE"
present = Rhino.Display.DisplayModeDescription.FindByName(PROBE_NAME) is not None
print("Present in a separate script run:", present)
Expected result
True — the probe mode was never deleted, so it should still be there.
Actual result
False. The probe mode is gone. GetDisplayModes() in this second run also shows several other modes have reverted to an older state (in our case, some display modes we’d deleted in earlier, unrelated sessions were back too), consistent with the whole list being reset to a stale snapshot rather than just our probe specifically disappearing.
Additional notes
- Reproduced with
rs.AddAliasalone, and separately withrs.DeleteAliasalone — either is independently sufficient. - Not tied to command-line nesting: wrapping the display-mode-affecting code in its own separate
-ScriptEditor Runcommand invoked from inside the alias-touching script doesn’t help — the reset still eventually surfaces on the next external check. - Not a one-off timing fluke tied to Rhino’s idle loop as far as we could tell — we tried explicitly pumping idle via
Rhino.RhinoApp.Wait()and subscribing a one-shotRhino.RhinoApp.Idlehandler to redo the display-mode fix after the alias call; the reset still eventually reappeared on a later check regardless. - Once no further alias is added/removed, the display mode state is stable indefinitely (verified with repeated checks across separate runs) — so this really does look tied specifically to alias add/remove, not a general periodic resync.
Question
Is this expected behavior (e.g. aliases and display modes sharing some cached “Options” profile object that gets naively reloaded/rewritten on alias changes), or a bug? Is there a way to force a flush/commit of Display Mode changes so they survive a subsequent alias change?
Happy to provide more detail, a screen recording, or test a build, this has cost us a fair amount of debugging time since it looks like flaky/racy script logic when it actually seems to be a Rhino-side state reset.