Unable to Close Transaction in GHPython Component

Hello,
I am trying to write a GHPython script for Rhino Inside Revit that will iterate through a folder of families and assign the built-in material parameter for the family geometry to a shared family parameter. I created the families using Rhino Inside Revit and a custom generic model template, but I was unable to associate the geometry to the family parameter at time of creation. I am hoping to process these families after the fact, but I am getting a transaction error. Any advice would be appreciated!

Here is the code block:

import clr
clr.AddReference('System.Core')
clr.AddReference('RhinoInside.Revit')
clr.AddReference('RevitAPI') 
clr.AddReference('RevitAPIUI')

from System import Enum

import rhinoscriptsyntax as rs
import os
import Rhino
import RhinoInside
import Grasshopper
from Grasshopper.Kernel import GH_RuntimeMessageLevel as RML
from RhinoInside.Revit import Revit, Convert
from Autodesk.Revit import DB, UI
import Autodesk.Revit.ApplicationServices as AS

def show_warning(msg):
    ghenv.Component.AddRuntimeMessage(RML.Warning, msg)

def show_error(msg):
    ghenv.Component.AddRuntimeMessage(RML.Error, msg)

def show_remark(msg):
    ghenv.Component.AddRuntimeMessage(RML.Remark, msg)

def assoc_elem_param_to_fam_param(family_path, built_in_param_name, family_param_name):
    # Define current application
    app = Revit.ActiveDBApplication
    
    
    # Get default document and document path
    original_doc = Revit.ActiveDBDocument
    default_path = original_doc.PathName
    
    
    # Open family file
    print family_path
    family_doc = app.OpenDocumentFile(family_path)
    
    
    # Establish family-specific variables
    family_manager = family_doc.FamilyManager
    family_params = family_manager.GetParameters()
    
    # Get element geometry
    
    collector = DB.FilteredElementCollector(family_doc)
    element = collector.OfClass(DB.FreeFormElement).ToElements()
    built_in_param = DB.BuiltInParameter[built_in_param_name]
    element_param = element[0].Parameter[built_in_param]
    
    
    # Get material shared parameter
    param_list = []
    for f in family_params:
        if f.Definition.Name == _family_param_name:
            param_list.append(f)
        else:
            continue
    
    material_parameter = param_list[0]
    
    
    # Associate parameter in family document
    with DB.Transaction(family_doc, "New Transaction") as t:
        
        try:
            t.Start()
            
            family_manager.AssociateElementParameterToFamilyParameter(element_param, material_parameter)
            
            t.Commit()
    
        except Exception as e:
            t.RollBack()
            show_error(str(e))
            print str(e)
        
        if t.HasStarted() and not t.HasEnded():
            t.RollBack()
    
    # Close the family file
    family_doc.Save()
    family_doc.Close(False)


# List all files and subdirectories
all_files_and_dirs = os.listdir(_directory_path)

# Get files in directory
files = [f for f in all_files_and_dirs if os.path.isfile(os.path.join(_directory_path, f))]
file_paths = [os.path.join(_directory_path, f) for f in files]

# Run script
if run:
    for path in file_paths:
        assoc_elem_param_to_fam_param(path, _built_in_param_name, _family_param_name)

And here is the error code:

Runtime error (InvalidOperationException): Unable to close all open transaction phases!

Traceback:
  line 85, in assoc_elem_param_to_fam_param, "<string>"
  line 105, in script

Line 85: family_doc.Save()

I don’t understand why the transaction is still open, or if there is some other transaction I created that might be causing this error. Script and sample families are attached below:

AssocElementParamToFamParam.zip (16.0 MB)

Thank you!

Update

For some reason, switching to a different GH document and then switching back resolved the issue, and the script ran perfectly. I am unsure if reloading the GH document window resolved the error or not, but it did work.

1 Like