Repository: godotengine/godot (language: cpp)

Issue:
[RC3] Godot crash when you try to replace resource with missing UID file
### Tested versions

 - RC2 / RC3
 


### System information

Linux, x86_64

### Issue description

I have  resource (my.tres) file with ref on Script.gd (extends Resource)
I deleted Script.gd.uid
When project opened I see warning: 
`WARNING: scene/resources/resource_format_text.cpp:447 - res://....tres:3 - ext_resource, invalid UID: uid://... - using text path instead:...Settings.gd`

Then doubleckick on `.tres` file for open in Inspector, I see this messages:
`ERROR: Unrecognized UID: "uid://.....". at: get_id_path (core/io/resource_uid.cpp:170)
ERROR: Resource file not found:  (expected type: )  at: _load (core/io/resource_loader.cpp:344)`

![Image](https://github.com/user-attachments/assets/beda5dff-f033-4fb4-84e0-2dcf008eb4b8)

If I drag-and-drop Settings.gd at `Script` property or use `Load` --  Godot crash
(Selected lines are error before crash)
![Image](https://github.com/user-attachments/assets/3b8ec64d-3d06-4db2-bc60-7c4a763fbcfd)

### Steps to reproduce

Delete .uid file
Try to replace ref resource

### Minimal reproduction project (MRP)

If need, my case is [this addon](https://github.com/ndbn/indent_guidelines)
Files are:
[Settings_4_3.tres](https://github.com/ndbn/indent_guidelines/blob/main/addons/indent_guidelines/Settings_4_3.tres) and [Settings.gd](https://github.com/ndbn/indent_guidelines/blob/main/addons/indent_guidelines/Settings.gd)


Discussion / hints:
This resource was also in use (plugin enabled)
If I disable plugin and reload project - sometimes I can replace script,
Tried as `Edit Dependencies` menu - work, `.tres` file saved with new UID for scipt Settings.gd
But field in file `metadata/_custom_type_script = "uid://ckdw6kn0pa4bj"` keep old UID
No idea how to change it with editor.

If I try drag-and-drop script with disabled plugin it sometime crash, sometimes just show message (like selected above) 
I deleted line `metadata/_custom_type_script = ` and try to reproduce - delete .uid file.
No crash, I can drag-and-frop Script file, and this line not appear in existing .tres file.

But if I create new Resource file based on same Settings.gd this line created again in .tres file, seems problem only with it.

[mrp_uid.zip](https://github.com/user-attachments/files/19041636/mrp_uid.zip)
Created MRP
1. Delete Script.gd.uid
2. Open project
3. Double click on test.tres
4. Clean Attached Script with round spinner icon
5. Drag and drop Script.gd in this field
6. Repeat if not crashed

Seems related #103045 
_Edit: Do you need testers for these kind of issues / should I continue to try and reproduce bugs?_

Unable to reproduce on MacOS 15.3.1 / RC2.

Do note that I dont get the spinner icon in step 4. Console just shows:

```
Godot Engine v4.4.rc2.official (c) 2007-present Juan Linietsky, Ariel Manzur & Godot Contributors.
--- Debug adapter server started on port 6006 ---
--- GDScript language server started on port 6005 ---
  WARNING: editor/editor_file_system.cpp:1338 - Missing .uid file for path "res://Script.gd". The file was re-created from cache.

```
I'm getting this stack trace:
```
ERROR: FATAL: DEV_ASSERT failed  "!thread_load_tasks.has(local_path)" is false.
   at: ResourceLoader::_load_start (C:\godot_source\core/io/resource_loader.cpp:627)

================================================================
CrashHandlerException: Program crashed
Engine version: Godot Engine v4.4.rc.custom_build (15ff450680a40391aabbffde0a57ead2cd84db56)
Dumping the backtrace. Please include this when reporting the bug to the project developer.
[0] ResourceLoader::_load_start (C:\godot_source\core\io\resource_loader.cpp:627)
[1] ResourceLoader::_load_start (C:\godot_source\core\io\resource_loader.cpp:627)
[2] ResourceLoader::load (C:\godot_source\core\io\resource_loader.cpp:548)
[3] PropertyUtils::get_custom_type_script (C:\godot_source\scene\property_utils.cpp:310)
[4] PropertyUtils::get_property_default_value (C:\godot_source\scene\property_utils.cpp:96)
[5] EditorPropertyRevert::get_property_revert_value (C:\godot_source\editor\editor_inspector.cpp:667)
[6] EditorPropertyRevert::can_property_revert (C:\godot_source\editor\editor_inspector.cpp:673)
[7] EditorProperty::update_editor_property_status (C:\godot_source\editor\editor_inspector.cpp:745)
[8] EditorInspector::update_tree (C:\godot_source\editor\editor_inspector.cpp:3840)
[9] EditorInspector::edit (C:\godot_source\editor\editor_inspector.cpp:4040)
[10] EditorNode::_edit_current (C:\godot_source\editor\editor_node.cpp:2561)
[11] EditorNode::push_item (C:\godot_source\editor\editor_node.cpp:2415)
[12] InspectorDock::_resource_selected (C:\godot_source\editor\inspector_dock.cpp:394)
[13] InspectorDock::edit_resource (C:\godot_source\editor\inspector_dock.cpp:478)
[14] EditorNode::load_resource (C:\godot_source\editor\editor_node.cpp:1372)
[15] FileSystemDock::_select_file (C:\godot_source\editor\filesystem_dock.cpp:1282)
[16] FileSystemDock::_tree_activate_file (C:\godot_source\editor\filesystem_dock.cpp:1302)
[17] call_with_variant_args_helper<FileSystemDock> (C:\godot_source\core\variant\binder_common.h:320)
[18] call_with_variant_args<FileSystemDock> (C:\godot_source\core\variant\binder_common.h:430)
[19] CallableCustomMethodPointer<FileSystemDock,void>::call (C:\godot_source\core\object\callable_method_pointer.h:109)
[20] Callable::callp (C:\godot_source\core\variant\callable.cpp:58)
[21] Object::emit_signalp (C:\godot_source\core\object\object.cpp:1237)
[22] Node::emit_signalp (C:\godot_source\scene\main\node.cpp:4022)
[23] Object::emit_signal<> (C:\godot_source\core\object\object.h:933)
[24] Tree::gui_input (C:\godot_source\scene\gui\tree.cpp:3918)
[25] Control::_call_gui_input (C:\godot_source\scene\gui\control.cpp:1826)
[26] Viewport::_gui_call_input (C:\godot_source\scene\main\viewport.cpp:1627)
[27] Viewport::_gui_input_event (C:\godot_source\scene\main\viewport.cpp:1860)
[28] Viewport::push_input (C:\godot_source\scene\main\viewport.cpp:3283)
[29] Window::_window_input (C:\godot_source\scene\main\window.cpp:1705)
[30] call_with_variant_args_helper<Window,Ref<InputEvent> const &,0> (C:\godot_source\core\variant\binder_common.h:315)
[31] call_with_variant_args<Window,Ref<InputEvent> const &> (C:\godot_source\core\variant\binder_common.h:430)
[32] CallableCustomMethodPointer<Window,void,Ref<InputEvent> const &>::call (C:\godot_source\core\object\callable_method_pointer.h:109)
[33] Callable::callp (C:\godot_source\core\variant\callable.cpp:58)
[34] Callable::call<Ref<InputEvent> > (C:\godot_source\core\variant\variant.h:961)
[35] DisplayServerWindows::_dispatch_input_event (C:\godot_source\platform\windows\display_server_windows.cpp:4275)
[36] DisplayServerWindows::_dispatch_input_events (C:\godot_source\platform\windows\display_server_windows.cpp:4246)
[37] Input::_parse_input_event_impl (C:\godot_source\core\input\input.cpp:905)
[38] Input::flush_buffered_events (C:\godot_source\core\input\input.cpp:1186)
[39] DisplayServerWindows::process_events (C:\godot_source\platform\windows\display_server_windows.cpp:3659)
[40] OS_Windows::run (C:\godot_source\platform\windows\os_windows.cpp:2075)
[41] widechar_main (C:\godot_source\platform\windows\godot_windows.cpp:97)
[42] _main (C:\godot_source\platform\windows\godot_windows.cpp:122)
[43] main (C:\godot_source\platform\windows\godot_windows.cpp:136)
[44] WinMain (C:\godot_source\platform\windows\godot_windows.cpp:150)
[45] __scrt_common_main_seh (D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288)
[46] <couldn't map PC to fn name>
-- END OF BACKTRACE --
```
but it's specifically crashing on DEV_ASSERT, so it's probably different from the OP.
Errors from drag-and-drop Script.gd into .tres `Script` property
Crash - on click `back to default` round arrow

![Image](https://github.com/user-attachments/assets/7ba74798-1e75-4be6-92e2-5bab342a438f)
Last error and crash on drag-and-drop script:

![Image](https://github.com/user-attachments/assets/5835000f-f2ff-49ef-9f61-b35109f537ca)
Same as above (drag-and-drop crash) but stack trace is different and biger

![Image](https://github.com/user-attachments/assets/8769863e-b0bd-4de5-9617-576c0b3f2f97)

![Image](https://github.com/user-attachments/assets/71b63890-c7d9-4ad9-ac8f-7e37517ef81c)
The crash is odd. It crashes when it tries to load invalid UID. When the UID is valid it works correctly.
An easy fix is checking whether UID is valid before loading, but it also points to some ResourceLoader bug.

Fix patch:
diff --git a/editor/scene_tree_dock.cpp b/editor/scene_tree_dock.cpp
index 2bc022f1d1cb..267d35f99458 100644
--- a/editor/scene_tree_dock.cpp
+++ b/editor/scene_tree_dock.cpp
@@ -3115,6 +3115,7 @@ void SceneTreeDock::_replace_node(Node *p_node, Node *p_by_node, bool p_keep_pro
 		// If we're dealing with a custom node type, we need to create a default instance of the custom type instead of the native type for property comparison.
 		if (oldnode->has_meta(SceneStringName(_custom_type_script))) {
 			Ref<Script> cts = PropertyUtils::get_custom_type_script(oldnode);
+			ERR_FAIL_COND_MSG(cts.is_null(), "Invalid custom type script.");
 			default_oldnode = Object::cast_to<Node>(get_editor_data()->script_class_instance(cts->get_global_name()));
 			if (default_oldnode) {
 				default_oldnode->set_name(cts->get_global_name());
diff --git a/scene/property_utils.cpp b/scene/property_utils.cpp
index dc9a56a294a9..75c16a4228d2 100644
--- a/scene/property_utils.cpp
+++ b/scene/property_utils.cpp
@@ -306,5 +306,12 @@ Ref<Script> PropertyUtils::get_custom_type_script(const Object *p_object) {
 		return script_object;
 	}
 #endif
+	ResourceUID::ID id = ResourceUID::get_singleton()->text_to_id(custom_script);
+	if (unlikely(id == ResourceUID::INVALID_ID || !ResourceUID::get_singleton()->has_id(id))) {
+		const_cast<Object *>(p_object)->remove_meta(SceneStringName(_custom_type_script));
+		ERR_FAIL_V_MSG(Ref<Script>(), vformat("Invalid custom type script UID: %s. Removing.", custom_script.operator String()));
+	} else {
+		custom_script = ResourceUID::get_singleton()->get_id_path(id);
+	}
 	return ResourceLoader::load(custom_script);
 }


Test patch: