Repository: godotengine/godot (language: cpp)

Issue:
Editor crash when inspecting 2 Objects handled by the same plugin, caused by corrupted ObjectID
### Tested versions

4.4

### System information

W10

### Issue description

When trying to edit 2 objects handled by the same plugin (e.g. by unfolding them in the inspector), the editor may sometimes print an error:
```
Condition "slot >= slot_max" is true. Returning nullptr.
```
It comes from here, and judging from the comment, it's not supposed to happen:

https://github.com/godotengine/godot/blob/cae3d722a3abd6d93d84a84beccc65a78948653f/core/object/object.h#L1047

And indeed, the ObjectID is corrupted, because sometimes you'll get this crash:
```
CrashHandlerException: Program crashed
Engine version: Godot Engine v4.5.dev.custom_build (caa59c5611ee77a574d4eaf957f264ceeb17cbd3)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[0] ObjectID::operator!= (C:\godot_source\core\object\object_id.h:51)
[1] EditorNode::edit_item (C:\godot_source\editor\editor_node.cpp:2413)
[2] call_with_variant_args_helper<EditorNode,Object *,Object *,0,1> (C:\godot_source\core\variant\binder_common.h:319)
[3] call_with_variant_args<EditorNode,Object *,Object *> (C:\godot_source\core\variant\binder_common.h:429)
[4] CallableCustomMethodPointer<EditorNode,void,Object *,Object *>::call (C:\godot_source\core\object\callable_method_pointer.h:108)
[5] Callable::callp (C:\godot_source\core\variant\callable.cpp:58)
[6] CallQueue::_call_function (C:\godot_source\core\object\message_queue.cpp:221)
[7] CallQueue::flush (C:\godot_source\core\object\message_queue.cpp:270)
[8] SceneTree::physics_process (C:\godot_source\scene\main\scene_tree.cpp:537)
[9] Main::iteration (C:\godot_source\main\main.cpp:4462)
[10] OS_Windows::run (C:\godot_source\platform\windows\os_windows.cpp:2075)
[11] widechar_main (C:\godot_source\platform\windows\godot_windows.cpp:97)
[12] _main (C:\godot_source\platform\windows\godot_windows.cpp:122)
[13] main (C:\godot_source\platform\windows\godot_windows.cpp:136)
[14] WinMain (C:\godot_source\platform\windows\godot_windows.cpp:150)
[15] __scrt_common_main_seh (D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
[16] <couldn't map PC to fn name>
-- END OF BACKTRACE --
```
The error and crash seem to be random, not sure what exactly causes them.

### Steps to reproduce

1. Open the MRP
2. In Sample_Scene click the root node and open C 1 Resource
3. Open C 2. C 1 should close with an error
4. Try opening both resources and/or re-selecting the node
5. Sometimes crash or error

### Minimal reproduction project (MRP)

[mrp_crash_gdscript.zip](https://github.com/user-attachments/files/19165139/mrp_crash_gdscript.zip)
Unexpected errors when creating SpriteFrames:Condition “plugins_list.has(p_plugin)" is true.  
### Tested versions

- Reproducible：Godot4.0 stable, Godot4.0.1stable ,Godot4.0.2stable ,Godot 4.0.3stable ,Godot 4.0.4stable,Godot 4.1stable,Godot 4.1.1stable,Godot 4.1.2stable,Godot4.1.4stable,Godot4.2stable,Godot4.2.1stable ,Godot4.2.2stable,Godot4.3stable,Godot4.4.1dev,Godot4.4.2dev
- Not Reproducible：Godot3.6 stable

### System information

Windows10 - Godot 4.4.dev2 - Vulkan(Forward+)

### Issue description

<img width="1501" alt="4 4 2" src="https://github.com/user-attachments/assets/6925652b-c0f1-4a1b-8ab2-252e1133dfe0">
<img width="1920" alt="4 2 2" src="https://github.com/user-attachments/assets/6cb925bd-5be0-4a0b-9bc8-7e5a01405a72">

https://github.com/user-attachments/assets/e57d4a80-f46e-4839-951b-1f6612c5ac5f



After creating an AnimatedSprite2D, I added a new SpriteFrames. Clicking on it again triggers the warning: **'editor/editor_node.cpp:8116 - Condition "plugins_list.has(p_plugin)" is true'**. This bug also exists in Godot 4.3.1 stable and every godot 4 version

### Steps to reproduce

https://github.com/user-attachments/assets/a4abda81-5a10-499f-89b1-f56d49e47ec2



https://github.com/user-attachments/assets/a4abda81-5a10-499f-89b1-f56d49e47ec2
0.Open Godot 4.4 dev2.
1.Create a new scene with any type of root node (in this example, it's Node2D).
2.Add a child node of type AnimatedSprite2D.
3.Click on the AnimatedSprite2D node, and in the inspector under the AnimatedSprite2D section, click on Animation/Sprite Frames and create a new SpriteFrames.
4.**(Important) Click on the root node, then click back on the AnimatedSprite2D node, and click on Animation/Sprite Frames in the inspector under the AnimatedSprite2D section.**,
5.Check the Output.
6.Click on the root node again, then click back on the AnimatedSprite2D node. Repeat this step, and you will see that every time you click on the AnimatedSprite2D node, the error "editor/editor_node.cpp:8116 - Condition 'plugins_list.has(p_plugin)' is true" will be triggered in the Output.

### Minimal reproduction project (MRP)

[mrp-for-the-editor-editor_node.cpp-8116---condition--plugins_list.has(p_plugin)--is-true'.zip](https://github.com/user-attachments/files/17173715/mrp-for-the-editor-editor_node.cpp-8116---condition--plugins_list.has.p_plugin.--is-true.zip)

Editor Plugins not removed when Folding an ancestor Resource
### Tested versions

78c9f8ddd906273a5970518d54d2f5114d07b246

### System information

Windows 11

### Issue description

Possibly related to https://github.com/godotengine/godot/issues/103615, but I have been unable to reproduce the crash to know for sure.

This is a minor bug in the inspector a resource property, which had corresponding editor plugins associated with a descendent properties, does not cleanup editor plugins from the list if the ancestor property was folded. This is because the code associated with removing a plugin from the active list is only called if the exact property with an associated plugin which handles the type is deselected. If, however, an EditorPropertyResource which contains a property handled by an plugin is closed while the property handled by a plugin is open, it will not be removed from the active list and the editor will show a warning that it tried to add the plugin to the list twice while it is already open.

https://github.com/user-attachments/assets/3ca0cc80-f370-4d84-a65c-5c72d8791c12

### Steps to reproduce

* Create a MeshInstance.
* Assign it a ShaderMaterial.
* Assign the ShaderMaterial a Shader.
* Open the Shader property as shown in the video.
* Click on the ShaderMaterial property. to close it.
* Click on it again to reopen it and note the error.

### Minimal reproduction project (MRP)

N/A


Discussion / hints:
I can confirm this happens on Fedora 40 as well
<img width="707" alt="4 4 3" src="https://github.com/user-attachments/assets/6a023025-d4d3-4b35-b547-a3b5ce578f97">
still exists in 4.4 dev3



Can confirm this exist
**It still exist in 4.4dev4.**
<img width="1361" alt="Snipaste_2024-11-09_13-04-37" src="https://github.com/user-attachments/assets/42e97d44-feff-4b8c-bd12-d9051ba6eae3">
**It still exists in 4.4beta1.**
<img width="1293" alt="Image" src="https://github.com/user-attachments/assets/c3d2f547-9d90-4e08-8754-83712159ad71" />
**It still exists in 4.4beta2.**
<img width="1501" alt="Image" src="https://github.com/user-attachments/assets/d7523b69-9cc6-4449-a2d8-470a4c381a5b" />
I just encountered this problem with AnimatedSprite2D on 4.3.stable, the editor spits this error every time an AnimatedSprite2D node is selected and SpriteFrames tab is open.
![Image](https://github.com/user-attachments/assets/73e34a29-5d50-4897-8ea4-7c4a9916b4bc)

Thank you for updating, but there's no need to put a comment each pre-release to update this, you can update the list of versions in the original post, but otherwise this is assumed to still be happening unless something new happens
This seems to be the source of the problem:
https://github.com/godotengine/godot/blob/750640cede4741a6a526fa5172a199bbb1ac0758/editor/plugins/sprite_frames_editor_plugin.cpp#L2499-L2513

Apparently the SpriteFrames plugin is enabled whenever the user wants to edit AnimatedSprite2D node, or its `sprite_frames` editor property, so whenever the user switches from one to another the engine attempts to add the plugin again because technically we're editing a different object now.


Fix patch:
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index 0aec3cff8ddd..40dfe180555f 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -2397,22 +2397,39 @@ void EditorNode::edit_item(Object *p_object, Object *p_editing_owner) {
 			continue;
 		}
 
+		bool need_to_add = true;
+		List<EditorPropertyResource *> to_fold;
+
 		// If plugin is already associated with another owner, remove it from there first.
 		for (KeyValue<ObjectID, HashSet<EditorPlugin *>> &kv : active_plugins) {
-			if (kv.key != owner_id) {
-				EditorPropertyResource *epres = Object::cast_to<EditorPropertyResource>(ObjectDB::get_instance(kv.key));
-				if (epres && kv.value.has(plugin)) {
-					// If it's resource property editing the same resource type, fold it.
-					epres->fold_resource();
-				}
+			if (kv.key == owner_id || !kv.value.has(plugin)) {
+				continue;
+			}
+			EditorPropertyResource *epres = Object::cast_to<EditorPropertyResource>(ObjectDB::get_instance(kv.key));
+			if (epres) {
+				// If it's resource property editing the same resource type, fold it later to avoid premature modifications
+				// that may result in unsafe iteration of active_plugins.
+				to_fold.push_back(epres);
+			} else {
 				kv.value.erase(plugin);
+				need_to_add = false;
+			}
+		}
+
+		if (!need_to_add && to_fold.is_empty()) {
+			plugin->make_visible(true);
+			plugin->edit(p_object);
+		} else {
+			for (EditorPropertyResource *epres : to_fold) {
+				epres->fold_resource();
 			}
+
+			// TODO: Call the function directly once a proper priority system is implemented.
+			to_over_edit.push_back(plugin);
 		}
 
 		// Activate previously inactive plugin and edit the object.
 		active_plugins[owner_id].insert(plugin);
-		// TODO: Call the function directly once a proper priority system is implemented.
-		to_over_edit.push_back(plugin);
 	}
 
 	for (EditorPlugin *plugin : to_over_edit) {


Test patch: