Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

Editor prints "Can't use get_node() with absolute paths from outside the active scene tree" when quitting with a node selected

Open
#1,516 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
Half a day
Newbie friendliness
52/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
cpp
Domain
devtools, game-dev

Research direction

The error comes from SceneTreeEditor::_selection_changed() in editor/scene/scene_tree_editor.cpp, reached through the deferred EditorSelection change flushed by EditorResourcePreview::stop() during shutdown. Build the editor, then run the four-file reproduction project with --quit-after 2400 and check stderr. Done means the get_node error no longer appears on normal and restricted runs, and the editor still reapplies selection when the scene tree is entered again.

Written by the indexing model from the issue text.

Description

Tested versions
  • Reproducible in v26.3.stable.official [85e5203945] (official Windows build).
  • Reproducible in local MSVC and LLVM-MinGW builds of 85e5203945, and in local builds of 26.3-rc.3 (ccb92435bb) and PR #1505 head c099442.
System information

Windows 10 22H2 (build 19045), x86-64. Forward+ (Vulkan 1.4), NVIDIA GeForce RTX 4080 SUPER, driver 616.56.

Issue description

When the editor quits while a node in the open scene is selected, it prints an error during shutdown:

ERROR: Can't use get_node() with absolute paths from outside the active scene tree.
   at: Node::get_node_or_null (scene/main/node.cpp:1874)

It is harmless (exit code 0, no crash), but every such quit produces an unexplained error. The error does not involve WorldScape or any addon logic: the reproduction project below contains only two Node3Ds.

Cause. A temporary diagnostic build printed this backtrace when the error fired. The build was based on 26.3-rc.3 with an extra print added to node.cpp, so line numbers are approximate; the code path is identical in 26.3-stable. The offending node is the Scene dock's SceneTreeEditor, which has already left the tree:

Node::get_node_or_null                    scene/main/node.cpp
Node::has_node                            scene/main/node.cpp
SceneTreeEditor::_update_selection        editor/scene/scene_tree_editor.cpp:1747
Object::emit_signalp
EditorSelection::_emit_change             editor/editor_data.cpp   (call_deferred)
CallQueue::flush
EditorResourcePreview::stop               editor/inspector/editor_resource_preview.cpp:606
EditorResourcePreview::_notification      (NOTIFICATION_EXIT_TREE)
Node::_propagate_exit_tree
SceneTree::finalize                       scene/main/scene_tree.cpp  (root->_set_tree(nullptr))

The sequence is:

  1. During SceneTree::finalize, the selected edited-scene node exits the tree.
  2. EditorSelection reacts by queueing _emit_change with call_deferred.
  3. Later in the same exit propagation, EditorResourcePreview::stop() flushes the message queue.
  4. selection_changed reaches SceneTreeEditor, which is already outside the tree. _update_selection() then calls has_node() with the tree items' absolute paths.

SceneTreeEditor::_update_tree() already returns early when the editor is outside the tree; _selection_changed() has no such check.

Proposed fix: https://github.com/dominicbytes/redot-engine/pull/3, based on redot-26.3-stable. It makes _selection_changed() return early while the editor is outside the tree, the same way _update_tree() does. Selection is reapplied by _update_tree() / _add_nodes() when the editor enters the tree again.

void SceneTreeEditor::_selection_changed() {
	// A deferred selection change can be flushed after this editor has left the tree
	// during shutdown. Selection is reapplied by _update_tree() when it enters again.
	if (!editor_selection || !is_inside_tree()) {
		return;
	}

With the change, the reproduction below exits 0 with no error in normal and restricted (Low-integrity) runs, with both MSVC and LLVM-MinGW builds. The tested builds also contained the separate WorldScape shutdown fix (dominicbytes/redot-engine#2; see #1514).

This was found and diagnosed with AI assistance using automated, bounded editor runs. It still needs independent human review and manual testing.

Steps to reproduce
  1. Open a project with a scene that contains a child node.
  2. Select the child node in the Scene dock.
  3. Quit the editor while the node is still selected. To automate this, the plugin below selects a node and calls get_tree().quit(); --quit-after also works.
  4. Read the editor's stderr: the error above is printed during shutdown.

Automated, using the MRP below:

redot.windows.editor.x86_64.exe --editor --path <MRP folder> --quit-after 2400

The plugin opens check.tscn, selects Child, waits 12 frames and calls get_tree().quit(). The error appears in stderr on every run.

Minimal reproduction project (MRP)

Four files:

project.godot

config_version=5

[application]

config/name="Selection shutdown control (no WorldScape)"

[editor_plugins]

enabled=PackedStringArray("res://addons/selprobe/plugin.cfg")

check.tscn

[gd_scene format=3]

[node name="SelectionCheck" type="Node3D"]

[node name="Child" type="Node3D" parent="."]

addons/selprobe/plugin.cfg

[plugin]
name="selprobe"
description="Selects a node in an open scene, then quits."
author="local"
version="1.0"
script="probe.gd"

addons/selprobe/probe.gd

@tool
extends EditorPlugin

func _enter_tree() -> void:
	call_deferred("_run")

func _frames(count: int) -> void:
	for i in range(count):
		await get_tree().process_frame

func _run() -> void:
	await _frames(12)
	while EditorInterface.get_resource_filesystem().is_scanning():
		await _frames(2)
	EditorInterface.open_scene_from_path("res://check.tscn")
	await _frames(12)
	var child := EditorInterface.get_edited_scene_root().get_node("Child")
	EditorInterface.edit_node(child)
	EditorInterface.get_selection().clear()
	EditorInterface.get_selection().add_node(child)
	await _frames(12)
	print("SELPROBE_DONE")
	get_tree().call_deferred("quit", 0)
Dominant language
C++
Stars
6.1k
Forks
337
Avg merge
4d 16h
Merged PRs (30d)
53

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from Redot-Engine/redot-engine

All issues in Redot-Engine/redot-engine

Similar issues

More C++ issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.