# Buggy code
def save_options(self, sender, args):
    self._config.halftone = self.halftone.IsChecked
    self._config.transparency = self.transparency.IsChecked
    self._config.proj_line_color = self.proj_line_color.IsChecked
    self._config.proj_line_pattern = self.proj_line_pattern.IsChecked
    self._config.proj_line_weight = self.proj_line_weight.IsChecked
    self._config.proj_fill_color = self.proj_fill_color.IsChecked
    self._config.proj_fill_pattern = self.proj_fill_pattern.IsChecked
    self._config.proj_fill_pattern_visibility = (
        self.proj_fill_pattern_visibility.IsChecked
    )
    self._config.proj_bg_fill_color = self.proj_bg_fill_color.IsChecked
    self._config.proj_bg_fill_pattern = self.proj_bg_fill_pattern.IsChecked
    self._config.proj_bg_fill_pattern_visibility = (
        self.proj_bg_fill_pattern_visibility.IsChecked
    )

    self._config.cut_line_color = self.cut_line_color.IsChecked
    self._config.cut_line_pattern = self.cut_line_pattern.IsChecked
    self._config.cut_line_weight = self.cut_line_weight.IsChecked
    self._config.cut_fill_color = self.cut_fill_color.IsChecked
    self._config.cut_fill_pattern = self.cut_fill_pattern.IsChecked
    self._config.cut_fill_pattern_visibility = (
        self.cut_fill_pattern_visibility.IsChecked
    )
    self._config.cut_bg_fill_color = self.cut_bg_fill_color.IsChecked
    self._config.cut_bg_fill_pattern = self.cut_bg_fill_pattern.IsChecked
    self._config.cut_bg_fill_pattern_visibility = (
        self.cut_bg_fill_pattern_visibility.IsChecked
    )

    self._config.dim_override = self.dim_override.IsChecked
    self._config.dim_textposition = self.dim_textposition.IsChecked
    self._config.dim_above = self.dim_above.IsChecked
    self._config.dim_below = self.dim_below.IsChecked
    self._config.dim_prefix = self.dim_prefix.IsChecked
    self._config.dim_suffix = self.dim_suffix.IsChecked

    script.save_config()
    self.Close()


# Traceback (AttributeError)
IronPython Traceback:
Traceback (most recent call last):
File "C:\Users\rob.cross\AppData\Roaming\pyRevit-Master\extensions\pyRevitTools.extension\pyRevit.tab\Modify.panel\Match.pushbutton\config.py", line 158, in
File "C:\Users\rob.cross\AppData\Roaming\pyRevit-Master\extensions\pyRevitTools.extension\pyRevit.tab\Modify.panel\Match.pushbutton\config.py", line 127, in save_options
AttributeError: 'MatchPropConfigWindow' object has no attribute 'proj_bg_fill_color'


Script Executor Traceback:
System.MissingMemberException: 'MatchPropConfigWindow' object has no attribute 'proj_bg_fill_color'
at IronPython.Runtime.Binding.MetaUserObject.FastGetBinderHelper.<>c__DisplayClass16_0.b__1(CallSite site, Object self, CodeContext context)
at IronPython.Runtime.Types.GetMemberDelegates.SlotDict(CallSite site, Object self, CodeContext context)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run4[T0,T1,T2,T3,TRet](T0 arg0, T1 arg1, T2 arg2, T3 arg3)
at IronPython.Compiler.PythonCallTargets.OriginalCallTarget3(PythonFunction function, Object arg0, Object arg1, Object arg2)
at CallSite.Target(Closure , CallSite , Object , Object , RoutedEventArgs )
at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
at _Scripting_(Object[] , Object , RoutedEventArgs )
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.Controls.Primitives.ButtonBase.OnClick()
at System.Windows.Controls.Button.OnClick()
at System.Windows.Controls.Primitives.ButtonBase.OnMouseLeftButtonUp(MouseButtonEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
at System.Windows.Input.InputManager.ProcessStagingArea()
at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean&amp; handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean&amp; handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean&amp; handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG&amp; msg)
at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
at System.Windows.Window.ShowHelper(Object booleanBox)
at System.Windows.Window.ShowDialog()
at Microsoft.Scripting.Interpreter.FuncCallInstruction`2.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run3[T0,T1,T2,TRet](T0 arg0, T1 arg1, T2 arg2)
at System.Dynamic.UpdateDelegates.UpdateAndExecute2[T0,T1,TRet](CallSite site, T0 arg0, T1 arg1)
at Microsoft.Scripting.Interpreter.DynamicInstruction`3.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.Interpreter.Run(InterpretedFrame frame)
at Microsoft.Scripting.Interpreter.LightLambda.Run2[T0,T1,TRet](T0 arg0, T1 arg1)
at IronPython.Compiler.PythonScriptCode.RunWorker(CodeContext ctx)
at PyRevitBaseClasses.ScriptExecutor.ExecuteScript(PyRevitCommandRuntime&amp; pyrvtCmd)

# Fixed code
def save_options(self, sender, args):
    # base
    self._config.halftone = self.halftone.IsChecked
    self._config.transparency = self.transparency.IsChecked

    # projection lines
    self._config.proj_line_color = self.proj_line_color.IsChecked
    self._config.proj_line_pattern = self.proj_line_pattern.IsChecked
    self._config.proj_line_weight = self.proj_line_weight.IsChecked

    # projection forground pattern
    self._config.proj_fill_color = self.proj_fill_color.IsChecked
    self._config.proj_fill_pattern = self.proj_fill_pattern.IsChecked
    self._config.proj_fill_pattern_visibility = (
        self.proj_fill_pattern_visibility.IsChecked
    )

    # projection background pattern (Revit >= 2019)
    if HOST_APP.is_newer_than(2019, or_equal=True):
        self._config.proj_bg_fill_color = self.proj_bg_fill_color.IsChecked
        self._config.proj_bg_fill_pattern = self.proj_bg_fill_pattern.IsChecked
        self._config.proj_bg_fill_pattern_visibility = (
            self.proj_bg_fill_pattern_visibility.IsChecked
        )

    # cut lines
    self._config.cut_line_color = self.cut_line_color.IsChecked
    self._config.cut_line_pattern = self.cut_line_pattern.IsChecked
    self._config.cut_line_weight = self.cut_line_weight.IsChecked

    # cut forground pattern
    self._config.cut_fill_color = self.cut_fill_color.IsChecked
    self._config.cut_fill_pattern = self.cut_fill_pattern.IsChecked
    self._config.cut_fill_pattern_visibility = (
        self.cut_fill_pattern_visibility.IsChecked
    )

    # cut background pattern (Revit >= 2019)
    if HOST_APP.is_newer_than(2019, or_equal=True):
        self._config.cut_bg_fill_color = self.cut_bg_fill_color.IsChecked
        self._config.cut_bg_fill_pattern = self.cut_bg_fill_pattern.IsChecked
        self._config.cut_bg_fill_pattern_visibility = (
            self.cut_bg_fill_pattern_visibility.IsChecked
        )

    # dim overrides
    self._config.dim_override = self.dim_override.IsChecked
    self._config.dim_textposition = self.dim_textposition.IsChecked
    self._config.dim_above = self.dim_above.IsChecked
    self._config.dim_below = self.dim_below.IsChecked
    self._config.dim_prefix = self.dim_prefix.IsChecked
    self._config.dim_suffix = self.dim_suffix.IsChecked

    script.save_config()
    self.Close()