diff --git a/lib/elements/clone.py b/lib/elements/clone.py
index 9c3e3e3a4..5d0ae7fa1 100644
--- a/lib/elements/clone.py
+++ b/lib/elements/clone.py
@@ -181,7 +181,7 @@ class Clone(EmbroideryElement):
                 for clone in clones:
                     clone.replace_with(Clone(clone).resolve_clone()[0])
 
-            source_parent.remove(cloned_node)
+            cloned_node.delete()
 
         # Add the cloned node to be a sibling of this node
         parent.add(cloned_node)
diff --git a/lib/extensions/batch_lettering.py b/lib/extensions/batch_lettering.py
index 44ae75695..e595af246 100644
--- a/lib/extensions/batch_lettering.py
+++ b/lib/extensions/batch_lettering.py
@@ -163,7 +163,7 @@ class BatchLettering(InkstitchExtension):
         index = parent.index(lettering_group)
         if text_positioning_path is not None:
             parent.insert(index, text_positioning_path)
-        parent.remove(lettering_group)
+        lettering_group.delete()
 
     def generate_output_file(self, file_format, path, text, stitch_plan):
         text = text.replace('\n', '')
@@ -217,7 +217,7 @@ class BatchLettering(InkstitchExtension):
             index = parent.index(text_positioning_path)
             parent.insert(index, lettering_group)
             TextAlongPath(self.svg, lettering_group, text_positioning_path, self.options.text_position)
-            parent.remove(text_positioning_path)
+            text_positioning_path.delete()
 
         self.get_elements()
         stitch_groups = self.elements_to_stitch_groups(self.elements)
diff --git a/lib/extensions/break_apart.py b/lib/extensions/break_apart.py
index a2e34a987..3508bb280 100644
--- a/lib/extensions/break_apart.py
+++ b/lib/extensions/break_apart.py
@@ -159,4 +159,4 @@ class BreakApart(InkstitchExtension):
             el.set('d', str(d))
             el.set('transform', get_correction_transform(element.node))
             parent.insert(index, el)
-        parent.remove(element.node)
+        element.node.delete()
diff --git a/lib/extensions/cleanup.py b/lib/extensions/cleanup.py
index 366d85477..d59174f20 100644
--- a/lib/extensions/cleanup.py
+++ b/lib/extensions/cleanup.py
@@ -73,8 +73,8 @@ class Cleanup(InkstitchExtension):
 
         errormsg(_("{num_elements_removed} elements removed").format(num_elements_removed=num_elements_removed))
         for element in self.elements_to_remove:
-            element.getparent().remove(element)
+            element.delete()
 
         errormsg(_("{num_groups_removed} groups/layers removed").format(num_groups_removed=num_groups_removed))
         for group in self.groups_to_remove:
-            group.getparent().remove(group)
+            group.delete()
diff --git a/lib/extensions/convert_to_satin.py b/lib/extensions/convert_to_satin.py
index 83279f587..184bb8bdb 100644
--- a/lib/extensions/convert_to_satin.py
+++ b/lib/extensions/convert_to_satin.py
@@ -68,7 +68,7 @@ class ConvertToSatin(InkstitchExtension):
                     joined_satin.node.set('transform', correction_transform)
                     parent.insert(index, joined_satin.node)
 
-            parent.remove(element.node)
+            element.node.delete()
 
     def convert_path_to_satins(self, path, stroke_width, style_args, path_style, depth=0):
         try:
diff --git a/lib/extensions/convert_to_stroke.py b/lib/extensions/convert_to_stroke.py
index d5b1bec01..af6563dfb 100644
--- a/lib/extensions/convert_to_stroke.py
+++ b/lib/extensions/convert_to_stroke.py
@@ -49,7 +49,7 @@ class ConvertToStroke(InkstitchExtension):
             )
             parent.insert(parent.index(element.node), stroke_element)
             if not self.options.keep_satin:
-                parent.remove(element.node)
+                element.node.delete()
 
     def path_style(self, element):
         color = element.get_style('stroke', '#000000')
diff --git a/lib/extensions/cut_satin.py b/lib/extensions/cut_satin.py
index 132c727f6..ca69dde80 100644
--- a/lib/extensions/cut_satin.py
+++ b/lib/extensions/cut_satin.py
@@ -33,10 +33,10 @@ class CutSatin(InkstitchExtension):
                 split_point = command.target_point
                 command_group = command.use.getparent()
                 if command_group is not None and command_group.get('id').startswith('command_group'):
-                    command_group.getparent().remove(command_group)
+                    command_group.delete()
                 else:
-                    command.use.getparent().remove(command.use)
-                    command.connector.getparent().remove(command.connector)
+                    command.use.delete()
+                    command.connector.delete()
 
                 new_satins = satin.split(split_point)
                 if None in new_satins:
@@ -44,7 +44,7 @@ class CutSatin(InkstitchExtension):
                 transform = get_correction_transform(satin.node)
                 parent = satin.node.getparent()
                 index = parent.index(satin.node)
-                parent.remove(satin.node)
+                satin.node.delete()
                 for new_satin in new_satins:
                     new_satin.node.set('transform', transform)
                     parent.insert(index, new_satin.node)
diff --git a/lib/extensions/cutwork_segmentation.py b/lib/extensions/cutwork_segmentation.py
index c041e3591..73ba08d49 100644
--- a/lib/extensions/cutwork_segmentation.py
+++ b/lib/extensions/cutwork_segmentation.py
@@ -183,8 +183,7 @@ class CutworkSegmentation(InkstitchExtension):
 
         for element in self.elements:
             if isinstance(element, Stroke):
-                parent = element.node.getparent()
-                parent.remove(element.node)
+                element.node.delete()
 
     def path_style(self, element, color):
         # set stroke color and make it a running stitch - they don't want to cut zigzags
diff --git a/lib/extensions/display_stacking_order.py b/lib/extensions/display_stacking_order.py
index f9f83ca42..6a29ea16e 100644
--- a/lib/extensions/display_stacking_order.py
+++ b/lib/extensions/display_stacking_order.py
@@ -31,7 +31,7 @@ class DisplayStackingOrder(InkstitchExtension):
 
         # remove layer if empty
         if len(layer) == 0:
-            self.svg.remove(layer)
+            layer.delete()
 
     def insert_stacking_num(self, layer, num, position):
         text = inkex.TextElement(attrib={
@@ -49,7 +49,7 @@ class DisplayStackingOrder(InkstitchExtension):
 
         # Remove the existing layer
         if layer is not None:
-            layer.getparent().remove(layer)
+            layer.delete()
 
         layer = inkex.Group(attrib={
             'id': '__inkstitch_stacking_order__',
diff --git a/lib/extensions/fill_to_satin.py b/lib/extensions/fill_to_satin.py
index 689d00dac..285688d4f 100644
--- a/lib/extensions/fill_to_satin.py
+++ b/lib/extensions/fill_to_satin.py
@@ -135,7 +135,7 @@ class FillToSatin(InkstitchExtension):
         for element in self.elements:
             if not self.options.keep_originals or element.name == "Stroke":
                 try:
-                    element.node.getparent().remove(element.node)
+                    element.node.delete()
                 except AttributeError:
                     pass
 
diff --git a/lib/extensions/fill_to_stroke.py b/lib/extensions/fill_to_stroke.py
index 085b3c952..c1b5ce9d6 100644
--- a/lib/extensions/fill_to_stroke.py
+++ b/lib/extensions/fill_to_stroke.py
@@ -87,12 +87,12 @@ class FillToStroke(InkstitchExtension):
 
         # do not use a group in case there is only one line
         if len(lines) <= 1:
-            parent.remove(centerline_group)
+            centerline_group.delete()
             centerline_group = parent
 
         # clean up
         if not self.options.keep_original:
-            parent.remove(element.node)
+            element.node.delete()
 
         # insert new elements
         self._insert_elements(lines, centerline_group, index, element_id, element_label, transform, style)
@@ -262,7 +262,7 @@ class FillToStroke(InkstitchExtension):
             # it is possible, that we get one element twice (if it has both, a fill and a stroke)
             # this means that we already removed it from the svg and we can ignore the error.
             try:
-                cut_line.getparent().remove(cut_line)
+                cut_line.delete()
             except AttributeError:
                 pass
 
diff --git a/lib/extensions/gradient_blocks.py b/lib/extensions/gradient_blocks.py
index 55f014e4d..79665a10a 100644
--- a/lib/extensions/gradient_blocks.py
+++ b/lib/extensions/gradient_blocks.py
@@ -98,7 +98,7 @@ class GradientBlocks(InkstitchExtension):
                     block.set('inkstitch:fill_underlay_row_spacing_mm', end_row_spacing)
 
                 color_block_group.append(block)
-            parent.remove(element.node)
+            element.node.delete()
 
     def _element_to_path(self, shape):
         coords = list(shape.exterior.coords)
diff --git a/lib/extensions/jump_to_stroke.py b/lib/extensions/jump_to_stroke.py
index 3726aaef8..867b859f1 100644
--- a/lib/extensions/jump_to_stroke.py
+++ b/lib/extensions/jump_to_stroke.py
@@ -124,7 +124,7 @@ class JumpToStroke(InkstitchExtension):
                     block_ids.append(subpath_id)
                     parent.insert(index, subpath_element)
                     elements.append(Stroke(subpath_element))
-                parent.remove(node)
+                node.delete()
             else:
                 elements.append(element)
         self.elements = elements
@@ -172,10 +172,10 @@ class JumpToStroke(InkstitchExtension):
             if merged:
                 # remove last element (since it is merged)
                 last_parent = last_element.node.getparent()
-                last_parent.remove(last_element.node)
+                last_element.node.delete()
                 # remove parent group if empty
                 if len(last_parent) == 0:
-                    last_parent.getparent().remove(last_parent)
+                    last_parent.delete()
             return
 
         if merged:
diff --git a/lib/extensions/lettering_along_path.py b/lib/extensions/lettering_along_path.py
index 10e62dd68..dcce8e1ed 100644
--- a/lib/extensions/lettering_along_path.py
+++ b/lib/extensions/lettering_along_path.py
@@ -97,7 +97,7 @@ class TextAlongPath:
             except IndexError:
                 pass
             for glyph in text_group.iterchildren():
-                text_group.remove(glyph)
+                glyph.delete()
             rendered_text = font.render_text(
                 self.settings.text,
                 text_group,
diff --git a/lib/extensions/lettering_edit_json.py b/lib/extensions/lettering_edit_json.py
index 702b33582..b86c4fcb7 100644
--- a/lib/extensions/lettering_edit_json.py
+++ b/lib/extensions/lettering_edit_json.py
@@ -40,4 +40,4 @@ class LetteringEditJson(InkstitchExtension):
         frame.Show()
         app.MainLoop()
 
-        self.svg.remove(layer)
+        layer.delete()
diff --git a/lib/extensions/lettering_font_sample.py b/lib/extensions/lettering_font_sample.py
index 2da7d44e3..0db33b6f1 100644
--- a/lib/extensions/lettering_font_sample.py
+++ b/lib/extensions/lettering_font_sample.py
@@ -24,4 +24,4 @@ class LetteringFontSample(InkstitchExtension):
         app = LetteringFontSampleApp(layer=layer)
         app.MainLoop()
         if len(layer) == 0:
-            self.svg.remove(layer)
+            layer.delete()
diff --git a/lib/extensions/lettering_remove_kerning.py b/lib/extensions/lettering_remove_kerning.py
index 7507c0240..7ec497452 100644
--- a/lib/extensions/lettering_remove_kerning.py
+++ b/lib/extensions/lettering_remove_kerning.py
@@ -32,7 +32,7 @@ class LetteringRemoveKerning(InkstitchExtension):
                 kerning = svg.xpath(xpath, namespaces=NSS)
                 if kerning:
                     kerning = kerning[0]
-                    kerning.getparent().remove(kerning)
+                    kerning.delete()
                     fontfile.seek(0)
                     fontfile.write(etree.tostring(svg).decode('utf-8'))
                     fontfile.truncate()
diff --git a/lib/extensions/palette_split_text.py b/lib/extensions/palette_split_text.py
index a866f09bf..04a9f5169 100644
--- a/lib/extensions/palette_split_text.py
+++ b/lib/extensions/palette_split_text.py
@@ -58,4 +58,4 @@ class PaletteSplitText(InkstitchExtension):
 
                 y -= height
                 parent.insert(0, element)
-            parent.remove(text)
+            text.delete()
diff --git a/lib/extensions/print_pdf.py b/lib/extensions/print_pdf.py
index 0bdd9d814..bbfd94234 100644
--- a/lib/extensions/print_pdf.py
+++ b/lib/extensions/print_pdf.py
@@ -356,7 +356,7 @@ class Print(InkstitchExtension):
         # just bulk up the SVG.
         for layer in layers_and_groups:
             if layer is not stitch_plan_layer:
-                svg.remove(layer)
+                layer.delete()
 
         overview_svg = etree.tostring(svg).decode('utf-8')
         color_block_groups = stitch_plan_layer.getchildren()
diff --git a/lib/extensions/redwork.py b/lib/extensions/redwork.py
index 5e0ae5a3b..48a9da314 100644
--- a/lib/extensions/redwork.py
+++ b/lib/extensions/redwork.py
@@ -68,7 +68,7 @@ class Redwork(InkstitchExtension):
         # remove input elements
         if not self.options.keep_originals:
             for element in elements:
-                element.node.getparent().remove(element.node)
+                element.node.delete()
 
     def _ensure_starting_point(self, multi_line_string, starting_point):
         # returns a MultiLineString whose first  LineString starts close to  starting_point
@@ -97,7 +97,7 @@ class Redwork(InkstitchExtension):
             if command:
                 # remove command symbol
                 command_group = command.connector.getparent()
-                command_group.getparent().remove(command_group)
+                command_group.delete()
                 # return the first occurence directly
                 return command.target_point
 
diff --git a/lib/extensions/remove_embroidery_settings.py b/lib/extensions/remove_embroidery_settings.py
index 90c6d68c7..5534f04c8 100644
--- a/lib/extensions/remove_embroidery_settings.py
+++ b/lib/extensions/remove_embroidery_settings.py
@@ -48,7 +48,7 @@ class RemoveEmbroiderySettings(InkstitchExtension):
         xpath = ".//svg:g[starts-with(@id,'command_group')]"
         groups = find_elements(self.svg, xpath)
         for group in groups:
-            group.getparent().remove(group)
+            group.delete()
 
         # remove standalone commands and ungrouped object commands
         standalone_commands = ".//svg:use[starts-with(@xlink:href, '#inkstitch_')]|.//svg:path[starts-with(@id, 'command_connector')]"
@@ -66,7 +66,7 @@ class RemoveEmbroiderySettings(InkstitchExtension):
             connectors = find_elements(self.svg, xpath)
             for connector in connectors:
                 group = connector.getparent()
-                group.getparent().remove(group)
+                group.delete()
 
         # remove standalone commands and ungrouped object commands
         standalone_commands = ".//svg:use[starts-with(@xlink:href, '#inkstitch_{command}')]"
@@ -84,14 +84,14 @@ class RemoveEmbroiderySettings(InkstitchExtension):
                 group = element.getparent()
                 if group.getparent() is not None:
                     if group.get_id().startswith("command_group"):
-                        group.getparent().remove(group)
+                        group.delete()
                     else:
-                        group.remove(element)
+                        element.delete()
                 continue
             for command in find_commands(element):
                 if del_option in ('all', command.command):
                     group = command.connector.getparent()
-                    group.getparent().remove(group)
+                    group.delete()
 
     def remove_commands(self):
         if self.svg.selection:
@@ -110,7 +110,7 @@ class RemoveEmbroiderySettings(InkstitchExtension):
             self.remove_element(element)
 
     def remove_element(self, element):
-        element.getparent().remove(element)
+        element.delete()
 
     def remove_inkstitch_attributes(self, elements):
         param_to_remove = self.options.del_params
diff --git a/lib/extensions/reorder.py b/lib/extensions/reorder.py
index 2c10559d0..a2715e627 100644
--- a/lib/extensions/reorder.py
+++ b/lib/extensions/reorder.py
@@ -10,28 +10,19 @@ from .base import InkstitchExtension
 
 
 class Reorder(InkstitchExtension):
-    # Remove selected objects from the document and re-add them in the order they
-    # were selected.
+    # Re-stack elements in the order they were selected.
 
     def effect(self):
         objects = self.svg.selection
-
-        if not objects:
+        if len(objects) < 2:
             errormsg(_("Please select at least two elements to reorder."))
             return
 
-        for obj in objects:
-            if not obj == objects.first():
-                obj.getparent().remove(obj)
-
         insert_parent = objects[0].getparent()
-        insert_pos = insert_parent.index(objects[0])
+        insert_pos = insert_parent.index(objects[0]) + 1
 
-        insert_parent.remove(objects[0])
-
-        insert_parent[insert_pos:insert_pos] = objects
+        insert_parent[insert_pos:insert_pos] = list(objects)[1:]
 
 
 if __name__ == '__main__':
-    e = Reorder()
-    e.run()
+    Reorder().run()
diff --git a/lib/extensions/stitch_plan_preview_undo.py b/lib/extensions/stitch_plan_preview_undo.py
index af4c8722f..30f293bcb 100644
--- a/lib/extensions/stitch_plan_preview_undo.py
+++ b/lib/extensions/stitch_plan_preview_undo.py
@@ -20,7 +20,7 @@ def reset_stitch_plan(svg, delete_stitch_plan=True):
         display_method = layer.get(INKSTITCH_ATTRIBS['layer_visibility'], 'unchanged')
         invisible_layers = layer.get(INKSTITCH_ATTRIBS['invisible_layers'], '').split(",")
         if delete_stitch_plan:
-            layer.getparent().remove(layer)
+            layer.delete()
 
         if display_method == "unchanged":
             return
diff --git a/lib/extensions/stroke_to_lpe_satin.py b/lib/extensions/stroke_to_lpe_satin.py
index 3c0ed017c..6a6a846f1 100644
--- a/lib/extensions/stroke_to_lpe_satin.py
+++ b/lib/extensions/stroke_to_lpe_satin.py
@@ -156,7 +156,7 @@ class StrokeToLpeSatin(InkstitchExtension):
                 old_effect_element.set('pattern', pattern_path)
                 old_effect_element.set('copytype', copy_type)
             else:
-                old_effect_element.getparent().remove(old_effect_element)
+                old_effect_element.delete()
 
         # update path effect link
         current_effects[inkstitch_effect_position] = lpe.get_id(as_url=1)
diff --git a/lib/extensions/troubleshoot.py b/lib/extensions/troubleshoot.py
index 180fd751f..c69953eb9 100644
--- a/lib/extensions/troubleshoot.py
+++ b/lib/extensions/troubleshoot.py
@@ -46,8 +46,7 @@ class Troubleshoot(InkstitchExtension):
             self.add_descriptions(problem_types)
             self.remove_empty_layers()
         else:
-            svg = self.document.getroot()
-            svg.remove(self.troubleshoot_layer)
+            self.troubleshoot_layer.delete()
 
             message = _("All selected shapes are valid! ")
             message += "\n\n"
@@ -120,7 +119,7 @@ class Troubleshoot(InkstitchExtension):
             # Remove the old layer - they may have used tranfsorms
             # or moved it into an other group (which could lead to more transforms)
             # We don't want to deal with it.
-            layer.getparent().remove(layer)
+            layer.delete()
 
         layer = inkex.Group(attrib={
             'id': '__validation_layer__',
@@ -251,4 +250,4 @@ class Troubleshoot(InkstitchExtension):
     def remove_empty_layers(self):
         for layer in self.troubleshoot_layer.iterchildren(SVG_GROUP_TAG):
             if len(layer) == 0:
-                self.troubleshoot_layer.remove(layer)
+                layer.delete()
diff --git a/lib/gui/satin_multicolor/main_panel.py b/lib/gui/satin_multicolor/main_panel.py
index fd053731f..f3f118bc1 100644
--- a/lib/gui/satin_multicolor/main_panel.py
+++ b/lib/gui/satin_multicolor/main_panel.py
@@ -91,7 +91,7 @@ class MultiColorSatinPanel(wx.Panel):
         self.update_satin_elements()
         if not self.colorize_panel.keep_original.GetValue():
             for element in self.elements:
-                element.node.getparent().remove(element.node)
+                element.node.delete()
         self.close()
 
     def render_stitch_plan(self):
@@ -124,7 +124,7 @@ class MultiColorSatinPanel(wx.Panel):
     def update_satin_elements(self):
         # empty old groups
         for group in self.output_groups:
-            group.getparent().remove(group)
+            group.delete()
         self.output_groups = []
 
         overflow_left = self.colorize_panel.overflow_left.GetValue()
diff --git a/lib/gui/test_swatches.py b/lib/gui/test_swatches.py
index e5a43149e..4909134a0 100644
--- a/lib/gui/test_swatches.py
+++ b/lib/gui/test_swatches.py
@@ -172,7 +172,7 @@ class GenerateSwatchesFrame(wx.Frame):
                         self._set_param(new_element, param, param_value)
                     param_value += step
             # remove old element
-            element.getparent().remove(element)
+            element.delete()
 
     def _set_param(self, element, param, value):
         element.set(f'inkstitch:{ param }', value)
diff --git a/lib/lettering/font.py b/lib/lettering/font.py
index 383b3707a..64320c927 100644
--- a/lib/lettering/font.py
+++ b/lib/lettering/font.py
@@ -251,7 +251,7 @@ class Font(object):
                 continue
             # remove destination_group if it is empty
             if not bounding_box:
-                destination_group.remove(letter_group)
+                letter_group.delete()
                 continue
 
             line_width = bounding_box.width
diff --git a/lib/stitches/auto_satin.py b/lib/stitches/auto_satin.py
index 1495891eb..cca65d1b1 100644
--- a/lib/stitches/auto_satin.py
+++ b/lib/stitches/auto_satin.py
@@ -624,7 +624,7 @@ def add_trims(elements, trim_indices):
     just_trimmed = False
     for i, element in enumerate(elements):
         if just_trimmed and isinstance(element, Stroke):
-            element.node.getparent().remove(element.node)
+            element.node.delete()
             continue
 
         if i in trim_indices:
diff --git a/lib/stitches/utils/autoroute.py b/lib/stitches/utils/autoroute.py
index 0ae6bd7c3..409dec363 100644
--- a/lib/stitches/utils/autoroute.py
+++ b/lib/stitches/utils/autoroute.py
@@ -246,17 +246,12 @@ def remove_original_elements(elements, commands_only=False):
         for command in element.commands:
             command_group = command.use.getparent()
             if command_group is not None and command_group.get('id').startswith('command_group'):
-                remove_from_parent(command_group)
+                command_group.delete()
             else:
-                remove_from_parent(command.connector)
-                remove_from_parent(command.use)
+                command.connector.delete()
+                command.use.delete()
         if not commands_only:
-            remove_from_parent(element.node)
-
-
-def remove_from_parent(node):
-    if node.getparent() is not None:
-        node.getparent().remove(node)
+            element.node.delete()
 
 
 def create_new_group(parent, insert_index, label, correction_transform=True):
diff --git a/lib/svg/rendering.py b/lib/svg/rendering.py
index f43f29981..3cf301063 100644
--- a/lib/svg/rendering.py
+++ b/lib/svg/rendering.py
@@ -223,7 +223,7 @@ def color_block_to_paths(color_block, svg, destination, visual_commands, line_wi
 def render_stitch_plan(svg, stitch_plan, realistic=False, visual_commands=True, render_jumps=True, line_width=0.4) -> inkex.Group:
     layer_or_image = svg.findone(".//*[@id='__inkstitch_stitch_plan__']")
     if layer_or_image is not None:
-        layer_or_image.getparent().remove(layer_or_image)
+        layer_or_image.delete()
 
     layer = inkex.Group(attrib={
         'id': '__inkstitch_stitch_plan__',
diff --git a/lib/tartan/fill_element.py b/lib/tartan/fill_element.py
index 6666181e6..f4f691c2c 100644
--- a/lib/tartan/fill_element.py
+++ b/lib/tartan/fill_element.py
@@ -20,6 +20,6 @@ def prepare_tartan_fill_element(element: BaseElement) -> None:
         outer_group = parent_group.getparent()
         assert outer_group is not None, f"Tartan element {element.get_id()} should have a parent group"
         outer_group.insert(outer_group.index(parent_group), element)
-        outer_group.remove(parent_group)
+        parent_group.delete()
     # make sure the element is invisible
     element.style['display'] = 'inline'
diff --git a/lib/tartan/svg.py b/lib/tartan/svg.py
index 62d737c9b..1fd4b3add 100644
--- a/lib/tartan/svg.py
+++ b/lib/tartan/svg.py
@@ -70,7 +70,7 @@ class TartanSvgGroup:
             # remove everything but the tartan outline
             for child in parent_group.iterchildren():
                 if child != outline:
-                    parent_group.remove(child)
+                    child.delete()
             group = cast(Group, parent_group)
         else:
             group = Group()
diff --git a/lib/update.py b/lib/update.py
index e0f6129aa..6816bcd69 100644
--- a/lib/update.py
+++ b/lib/update.py
@@ -240,13 +240,13 @@ def reposition_legacy_command(command):
     # instead of calculating the transform for the new position, we take the easy route and remove
     # the old commands and set new ones
     add_commands(Stroke(element), [command_name], InkstitchPoint(*target_point))
-    command_group.getparent().remove(command_group)
+    command_group.delete()
 
 
 def _rename_command(document, symbol, old_name, new_name):
     symbol_id = symbol.get_id()
     if symbol_id.startswith(old_name):
-        symbol.getparent().remove(symbol)
+        symbol.delete()
         ensure_symbol(document, new_name)
         _update_command(document, symbol_id, new_name)