Tool Resource-Tool Node pair creates a new hanging signal connection with each rebuild

Godot Version

4.7.stable.mono

TL;DR Question

A [Tool] Node using a [Tool] Resource (created by following docs) creates a new hanging connection in Editor (no such issue in Game, due to cleanup in _ExitTree()) on each rebuild. How should I disconnect it?

Or maybe a better question is how do I make a node that reacts to resource changes in-editor (like some built-in nodes react to texture resource changes in editor), without having this issue with signals/connections?

In detail

In my game I’ve created a [Tool] node which changes, when a [Tool] resource changes. To do that I’ve followed a section from docs. I’ve noticed I was getting an increasing amount of System.NullReferenceException in editor errors on each rebuild. I investigated and found that each rebuild created a new hanging connection, which is confirmed by logging GetIncomingConnections().Count.

I’ve created a new project with just those elements to isolate the issue.

ToolResource.cs

using System;
using Godot;

[Tool]
[GlobalClass]
public partial class ToolResource : Resource
{
    private int _value;

    [Export]
    public int Value
    {
        get => _value;
        set
        {
            _value = value;
            EmitChanged();
        }
    }
}

ToolNode.cs

using System;
using Godot;

[Tool]
public partial class ToolNode : CsgBox3D
{
    private ToolResource _resource;

    [Export]
    public ToolResource Resource
    {
        get => _resource;
        set
        {
            if (_resource != null)
            {
                _resource.Changed -= OnResourceChanged;
                GD.Print($"-- {GetIncomingConnections().Count}");
            }

            _resource = value;

            if (_resource != null)
            {
                _resource.Changed += OnResourceChanged;
                GD.Print($"++ {GetIncomingConnections().Count}");
                OnResourceChanged();
            }
        }
    }

    private void OnResourceChanged()
    {
        Scale = new Vector3(_resource.Value, _resource.Value, _resource.Value);
        GD.Print($"== {GetIncomingConnections().Count}");
    }

    public override void _ExitTree()
    {
        if (_resource != null)
        {
            _resource.Changed -= OnResourceChanged;
            GD.Print($"-- {GetIncomingConnections().Count}");
        }
        base._ExitTree();
    }
}

As I’ve said, in-game the amount of connections is as expected:

++ 1
== 1
-- 0

While in-editor I get an increasing amount of errors and an increasing logged amount of connections:

++ 6
== 6

Attempted solutions

Disconnecting all incoming connections in the property setter

    private void DisconnectIncomingConnections()
    {
        foreach (Godot.Collections.Dictionary connection in GetIncomingConnections())
        {
            Signal signal = connection["signal"].As<Signal>();
            Callable callable = connection["callable"].As<Callable>();

            signal.Owner.Disconnect(signal.Name, callable);
        }
    }

Returns an error for each of those connections: ERROR: Attempt to disconnect a nonexistent connection from '<Resource#-9223370292259120180>'. Signal: 'changed', callable: 'Delegate::Invoke'.

Using Connect() and Disconnect(), instead of += and -=

In this docs article it says that Connect() disconnects automatically, so I tried using it:

// _resource.Changed += OnResourceChanged;
_resource.Connect(
    ToolResource.SignalName.Changed,
    Callable.From(OnResourceChanged)
);

No noticeable difference, unfortunately. Number of connections in-editor continues to increase.