"Attempt to disconnect a nonexistent connection" while deleting GraphNode from GraphEditor

Godot Version

v4.4.1.stable.official [49a5bc7b6]

Question

Similar to this question: GraphEdit nodes deletion error

When trying to delete GraphNode added using add_child, an error was given:

Attempt to disconnect a nonexistent connection from 'MusicGraphNode'. Signal: 'item_rect_changed', callable: 'CanvasItem::queue_redraw'.

I was using this code to delete node. However, I tested and I found, with only A, only B, and both A and B, that error was given. Changing free to queue_free does not solve the problem.

func clearUI():
    self.clear_connections()
    for c in self.get_children(): if c is GraphElement:
        self.remove_child(c) # A
        c.free() # B

If this clearUI called in _init, no error will be given. Also, I have checked that clearUI is only called once by theloadGraphFromAMUG method.

Also, as described in the link above, if using deferred call of add_child, no error will be given.

I am wondering why this is happening.

This is my code:

@tool
class_name MusicGraphEditor
extends GraphEdit
## This class is responsible to maintain the UI and inner data (`graph_store`).
## For each defined method, it should operate on GraphEdit's internal structure to show the UI,
##  and `graph_store: MusicGraph` for saving data.
# End of class document.


## The operation mode of MusicGraphEditor.
enum OperationMode
{
    select,
    move,
    connect,
    single_node_focusing
}

## Current graph showed on the editor UI.
var graph_store: MusicGraph

## Index of the graph_store in the file tab.[br]
var graph_index: int

## Counter used for new node creation.
var node_id_counter: int

## Counter used for new edge creation.
var edge_id_counter: int

## Current operation mode of UI.
var operation_mode: OperationMode: set = __setOperationMode
func __setOperationMode(m: OperationMode):
    print_debug(str("Set MusicGraphEditor's operation_mode to \"", OperationMode.find_key(m), "\"."))
    operation_mode = m


# TODO
func _init() -> void:
    self.add_child(
        MusicGraphNode.new(
            MusicNode.new(1,"Test1", null, null, Vector2(10,10), [
                GraphNodeSlotInfo.new(0, GraphNodeSlotInfo.SlotLocation.right),
                GraphNodeSlotInfo.new(1, GraphNodeSlotInfo.SlotLocation.right),
                GraphNodeSlotInfo.new(2, GraphNodeSlotInfo.SlotLocation.right),
                GraphNodeSlotInfo.new(3, GraphNodeSlotInfo.SlotLocation.left),
            ])
        )
    )
    self.add_child(
        MusicGraphNode.new(
            MusicNode.new(2,"Test2", null, null, Vector2(300,300), [
                GraphNodeSlotInfo.new(0, GraphNodeSlotInfo.SlotLocation.left),
                GraphNodeSlotInfo.new(1, GraphNodeSlotInfo.SlotLocation.left),
                GraphNodeSlotInfo.new(2, GraphNodeSlotInfo.SlotLocation.right),
            ])
        )
    )
    var connect_result = self.connect_node("Test1",1,"Test2",1)
    # self.clearUI() # If called from here, no error.

func _gui_input(event: InputEvent) -> void:
    self.__handleGUIInput__(event)

func __handleGUIInput__(event: InputEvent):
    # TODO
    # Written in this way to get type hint.
    if event is InputEventMouse: if event.is_pressed():
        var nearest_conn := self.get_closest_connection_at_point(event.position)
        # If found a connection.
        if nearest_conn.size() > 0:
            pass

func loadGraphFromAMUG(index: int, file: AMUGResource):
    self.graph_index = index
    self.graph_store = file.music_graph
    self.loadGraphFromStore()

## Load the UI and paramters from `self.graph_store`.
func loadGraphFromStore():
    # TODO
    self.clearUI()

    var node_array := self.graph_store.node_array
    for node in self.graph_store.node_array:
        self.add_child(MusicGraphNode.new(node))
    self.node_id_counter = node_array[-1].id + 1

func clearUI():
    self.clear_connections()
    for c in self.get_children(): if c is GraphElement:
        self.remove_child(c)
        c.free()
1 Like

I am still working with this solution in my editor. And yes, I am curious why and how this is working :grinning_face_with_smiling_eyes:

1 Like

I am also having this issue. (Commenting so this doesnt auto close)

If i find a solution will send