Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve error message for calling non-tool scripts from tool scripts #36592

Closed
aaronfranke opened this issue Feb 27, 2020 · 9 comments · Fixed by #94511
Closed

Improve error message for calling non-tool scripts from tool scripts #36592

aaronfranke opened this issue Feb 27, 2020 · 9 comments · Fixed by #94511

Comments

@aaronfranke
Copy link
Member

aaronfranke commented Feb 27, 2020

Godot version: 3.2+

OS/device including version: Applies to all versions.

Issue description:

if current_node.has_method("set_view_mode"):
        current_node.set_view_mode(view_mode_index)

This gave me the error message: Invalid call. Nonexistent function 'set_view_mode'

This was extremely confusing until I asked for help online and we realized that current_node's script was missing the tool keyword and this code was in a tool script. It would be very helpful if there was a better error message when this situation occurs. Perhaps something like:

Cannot run set_view_mode on base [whatever] in the editor because the script is not a tool script.

@theoway
Copy link
Contributor

theoway commented Feb 27, 2020

@aaronfranke I'm not getting your point. Could you please show the steps to reproduce the error?

@Zireael07
Copy link
Contributor

A tool script cannot use things from scripts that are not tool scripts themselves, simply put.

@theoway
Copy link
Contributor

theoway commented Feb 27, 2020

@Zireael07 I tried to reproduce it, but couldn't. I made a tool script and tried to call a method from a non-tool script, but it worked. My engine version is 3.2
If anyone is getting the error, please do tell how to reproduce it,

@dagophil
Copy link

I just ran into the same issue and created a small project to reproduce it. I am using Godot Engine v3.2.1.stable.official.

gd_tool_logs_error.zip

Steps to reproduce:

  • Open Scene.tscn of the attached project.
  • Select the SomeTool node
  • Assign the exported Entity Variable to the SomeNonTool Node. This produces a log error:
    res://SomeTool.gd:10 - Invalid call. Nonexistent function 'do_it' in base 'Node (SomeNonTool.gd)'.

The SomeTool node has the following script:

tool
extends Node

export var entity: NodePath setget _set_entity

func _set_entity(value: NodePath) -> void:
	entity = value
	var node := get_node_or_null(value)
	if node and node.has_method("do_it"):
		node.do_it()

@nhartung
Copy link

nhartung commented Aug 7, 2020

Confirmed on 3.2.2.

I have a tool script that does:

assert(parent.has_method("get_input_direction"))
var direction = parent.get_input_direction()

and the parent object (non-tool) in this case:

func get_input_direction():
	return InputLib.Movement.get_input_direction()

gives the error:
"Invalid call. Nonexistent function 'get_input_direction' in base 'Area2D (Player.gd)'.

What's most annoying about this is that the error message is constantly produced, at a fast rate. I left my PC running overnight and came back to Godot spiking my CPU until I cleared the Output window in the editor.

@nhartung
Copy link

nhartung commented Aug 7, 2020

Also, is it true that a tool script cannot call a function from a non-tool object? Essentially, is this intended to be an error, or not? It's not clear to me from the discussion above. I don't see why this can't be supported.

What's curious is that the assert statement doesn't give an error. Meaning, the interpreter clearly understands that the parent provides the function.

@Arnklit
Copy link
Contributor

Arnklit commented Nov 23, 2020

You can also run into this issue when calling non-tool scripts from stuff like EditorSpatialGizmoPlugin. Which is how I wasted half an hour not understanding why I got the error this morning. So it's any script that runs in Editor mode should give a warning if you are calling a function on another script that does not run in Editor mode.

@npip99
Copy link

npip99 commented Nov 21, 2023

This would be very helpful. Even doing plenty of research, "@tool at the top of the file" still doesn't shed light on the issue as my script did have @tool.

In my case, I had a @tool script calling a script that wasn't @tool, it wasn't clear even from the forums that this isn't allowed. Apparently at a lower-level, Godot instances placeholder scripts in the editor instead of the real script.

res://scripts/Tools.gd:20 - Invalid call. Nonexistent function 'regenerate_terrain' in base 'MeshInstance3D (TerrainMesh.gd)'.

Tools.gd was @tool, but TerriainMesh.gd wasn't; Error message should more clearly say "TerrainMesh.gd cannot be called from the editor without @tool!", or something of the like.

@juanjp600
Copy link
Contributor

I think there should be a diagnostic preventing tools from interacting with non-tool scripts, but that might be problematic because it would be a breaking change for at least one plugin that exists in the wild. It seems that, at least for GDScript, this is not an issue when a tool only accesses a non-tool's exported fields. It is still an issue for .NET, as seen in this sample project: Tool export mismatch.zip

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment