Why "!is_inside_tree()" is true and "get_viewport()" is null !?

Godot Version

v4.2.1.stable.official [b09f793f5]

Question

Hello, I have a plugin that can move its editor panel between different sections of the Godot editor, when it does this it appears in the console:

scene/main/canvas_item.cpp:1052 - Parameter "get_viewport()" is null.
scene/main/viewport.cpp:3390 - Condition "!is_inside_tree()" is true.

I tried to understand what is happening, to explain it I must first mention the method:

func _move_to(index):
	if place in [PLACE_TOOLBAR, PLACE_SPATIAL_EDITOR_MENU]:
		popup.hide()
	var file = FileAccess.open(PLACE, FileAccess.WRITE)
	file.store_string(str(index))
	file.close()
	_remove_panel()
	_add_panel()

This code is located in the main code of my plugin (the same plugin script), and it is being called correctly when it needs to be transferred somewhere else. Through a bit of trial and error, I figured out that the issue is in _remove_panel(). (As can be guessed from the errors) This function is responsible for removing the panel; all the variables used (including the panel, button, and popup specified in _enter_tree()) are set, and the problem must stem from one (or two) of them:

func _remove_panel():
	move_list.item_selected.disconnect(self._move_to)
	match place:
		PLACE_BOTTOM:
			remove_control_from_bottom_panel(panel)
		PLACE_TOOLBAR:
			remove_control_from_container(EditorPlugin.CONTAINER_TOOLBAR, button)
			EditorInterface.get_base_control().remove_child(popup)
			button.pressed.disconnect(self._show_popup)
		PLACE_SPATIAL_EDITOR_MENU:
			remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, button)
			EditorInterface.get_base_control().remove_child(popup)
			button.pressed.disconnect(self._show_popup)
		PLACE_SPATIAL_EDITOR_SIDE_LEFT:
			remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_SIDE_LEFT, panel)
		PLACE_SPATIAL_EDITOR_SIDE_RIGHT:
			remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_SIDE_RIGHT, panel)
		PLACE_SPATIAL_EDITOR_BOTTOM:
			remove_control_from_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_BOTTOM, panel)
		PLACE_CANVAS_EDITOR_MENU:
			EditorInterface.get_base_control().remove_child(popup)
			remove_control_from_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_MENU, button)
			button.pressed.disconnect(self._show_popup)
		PLACE_CANVAS_EDITOR_SIDE_LEFT:
			remove_control_from_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_SIDE_LEFT, panel)
		PLACE_CANVAS_EDITOR_SIDE_RIGHT:
			remove_control_from_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_SIDE_RIGHT, panel)
		PLACE_CANVAS_EDITOR_BOTTOM:
			remove_control_from_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_BOTTOM, panel)
		PLACE_INSPECTOR:
			remove_control_from_container(EditorPlugin.CONTAINER_INSPECTOR_BOTTOM, panel)
		_:
			remove_control_from_docks(panel)

What strikes me as strange is that when I deactivate the plugin, this function is also called from _exit_tree() and it works, but it doesn’t throw an error. However, if I call it from _move_to(), everything gets cleared and recreated in its correct place, but the two errors mentioned above are displayed. Do you have any ideas?

Additionally, for the complete code, you can go to the TopNote repository, and you’ll find these in the TopNote.gd file, although I am still in the process of refining it, and this code is not exactly the same as the repository code.

Note: You can see here for more information, but I can not find any sulotion from that issue…

This error makes sense, !is_inside_tree() means it is not inside the tree, the bang operator ! inverts a boolean, like == false. So your error is from something that isn’t inside the tree and cannot get the viewport.

I don’t see a func _add_panel() in your github repo but I’d suspect the error actually comes from there? What happens when the error occurs? A crash?

Yes, I am also confused about that. Do I need to be inside the tree to remove a panel from the editor? It doesn’t seem like it because the deletion occurs, and even when I move the panel from the bottom panel of the editor to where it is, it still gives an error. It’s clear that it only executes 2 lines of code, none of which give me an idea of why I should see the warning.

As I said, I have not finalized the changes yet; currently, _add_panel() is: (the same code that is at the end of _enter_ter(); I thought it might cause issues if I called it without exiting the editor, so I moved it to a separate function.)

func _add_panel():
	if place in [PLACE_TOOLBAR, PLACE_SPATIAL_EDITOR_MENU]:
		popup.add_child(panel)
	match place:
		PLACE_BOTTOM:
			add_control_to_bottom_panel(panel, "Top Note")
			make_bottom_panel_item_visible(panel)
		PLACE_TOOLBAR:
			EditorInterface.get_base_control().add_child(popup)
			add_control_to_container(EditorPlugin.CONTAINER_TOOLBAR, button)
			button.pressed.connect(self._show_popup)
		PLACE_SPATIAL_EDITOR_MENU:
			EditorInterface.get_base_control().add_child(popup)
			add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_MENU, button)
			button.flat = true
			button.pressed.connect(self._show_popup)
		PLACE_SPATIAL_EDITOR_SIDE_LEFT:
			add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_SIDE_LEFT, panel)
		PLACE_SPATIAL_EDITOR_SIDE_RIGHT:
			add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_SIDE_RIGHT, panel)
		PLACE_SPATIAL_EDITOR_BOTTOM:
			add_control_to_container(EditorPlugin.CONTAINER_SPATIAL_EDITOR_BOTTOM, panel)
		PLACE_CANVAS_EDITOR_MENU:
			EditorInterface.get_base_control().add_child(popup)
			add_control_to_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_MENU, button)
			button.flat = true
			button.pressed.connect(self._show_popup)
		PLACE_CANVAS_EDITOR_SIDE_LEFT:
			add_control_to_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_SIDE_LEFT, panel)
		PLACE_CANVAS_EDITOR_SIDE_RIGHT:
			add_control_to_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_SIDE_RIGHT, panel)
		PLACE_CANVAS_EDITOR_BOTTOM:
			add_control_to_container(EditorPlugin.CONTAINER_CANVAS_EDITOR_BOTTOM, panel)
		PLACE_INSPECTOR:
			add_control_to_container(EditorPlugin.CONTAINER_INSPECTOR_BOTTOM, panel)
		PLACE_SLOT_LEFT_UL:
			add_control_to_dock(EditorPlugin.DOCK_SLOT_LEFT_UL, panel)
		PLACE_SLOT_LEFT_BL:
			add_control_to_dock(EditorPlugin.DOCK_SLOT_LEFT_BL, panel)
		PLACE_SLOT_LEFT_UR:
			add_control_to_dock(EditorPlugin.DOCK_SLOT_LEFT_UR, panel)
		PLACE_SLOT_LEFT_BR:
			add_control_to_dock(EditorPlugin.DOCK_SLOT_LEFT_BR, panel)
		PLACE_SLOT_RIGHT_UL:
			add_control_to_dock(EditorPlugin.DOCK_SLOT_RIGHT_UL, panel)
		PLACE_SLOT_RIGHT_BL:
			add_control_to_dock(EditorPlugin.DOCK_SLOT_RIGHT_BL, panel)
		PLACE_SLOT_RIGHT_UR:
			add_control_to_dock(EditorPlugin.DOCK_SLOT_RIGHT_UR, panel)
		PLACE_SLOT_RIGHT_BR:
			add_control_to_dock(EditorPlugin.DOCK_SLOT_RIGHT_BR, panel)

No problem, everything works as it should. I can still work with buttons, pop-ups, and panels in any state, and it can be found throughout the editor. The only thing that shouldn’t happen is the error message that appears. If there was a visibly real issue alongside the error, troubleshooting might not have been so difficult, but that’s not the case. Despite the error message, everything is fine!

Edit: I have a way to eliminate the error that shows me roughly where the error is from. If you do not execute _remove_panel() (in the _exit_tree() repository) in the _move_to() function and comment it out, no error will be displayed. However, it cannot be kept this way, as in this case, the panels keep increasing more and more with each movement!

Update:

  • I change project version from v4.2.1.stable.official [b09f793f5] to v4.3.stable.official [77dcf97d8] and v4.4.beta3.official [06acfccf8], but it didn’t help.
  • The project is currently on v4.3.stable.official [77dcf97d8], and the repository has been fully updated.

Notification to @gertkeno

I’ll be honest I kind of accept that these types of errors can pop up with little effect, like CSGs (<4.4) and GridMaps spout a lot of errors despite running okay. It’s probably solveable but it sounds low priority. Plugins are a great system in Godot but they do need a little help with debugging.

1 Like