Bug: Removing custom container causes "Object reference not set to an instance of an object"
TouchGFX Designer: 4.26.0
I cannot share the project to reproduce the bug unfortunately.
I removed several custom containers in the Container tab. In several places in the Screens tab a yellow dot appeared for some now incomplete screen interactions (expected behavior). However, when generating sources/saving the project I got the following error
```txt
2026-07-16 14:45:05,342 [1] ERROR TouchGFXDesigner.App: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
at TouchGFXDomainModel.LoadSave.Serial.ToSerial.Convert(TriggerCustom t)
at TouchGFXDomainModel.LoadSave.Serial.ToSerial.Convert(Interaction i)
at System.Linq.Enumerable.IListSelectIterator`2.ToList()
at TouchGFXDomainModel.LoadSave.Serial.ToSerial.Convert(Screen s)
at System.Linq.Enumerable.IListSelectIterator`2.ToList()
at TouchGFXDomainModel.LoadSave.Serial.ToSerial.Convert(Application a)
at TouchGFXDomainModel.LoadSave.Serial.ToSerial.Convert(Model m)
at TouchGFXDomainModel.LoadSave.LoadSave.SaveDotTouchgfx(String filename, Model model)
at TouchGFXDomainModel.LoadSave.LoadSave.Save(String filename, Model model)
at TouchGFXApplication.MonitorCommands.SaveCommand.Execute()
at TouchGFXApplication.TouchGFXApplication.Save()
at TouchGFXDesigner.Main.Project.ProjectCommands.Save(Object obj)
at TouchGFXDesigner.Main.Project.ProjectCommands.PreCommandSteps()
at TouchGFXDesigner.Main.Project.ProjectCommands.GenerateCode(Object obj)
at ComponentViewModels.DelegateCommand.Execute(Object parameter)
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.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
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.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& handled)
at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& 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)
```This was caused by another incomplete interaction not showing up as invalid. It happened during several occasians when removing custom containers, but it did not always generate an error upon generating sources and/or saving the project. E.g. I had multiple interactions that were leftover from deleting a custom container which resulted in the .touchgfx json with interactions defined as TriggerCustom without a TriggerComponent. I fixed those programmatically using the following python code:
import json
jsonTree = json.loads(jsonString)
screens = jsonTree['Application']['Screens']
for screen in screens:
interactions = screen['Interactions']
for interaction in reversed(interactions): # reverse looping otherwise removing elements breaks the loop
trigger = interaction['Trigger']
if trigger['Type'] == 'TriggerCustom' and 'TriggerComponent' not in trigger.keys():
print('Deleting interaction "' + interaction['InteractionName'] + '" from screen "' + screen['Name'] + '"')
interactions.remove(interaction)
