godotengine / godotengine/godot

`load()` returns `GDScript` even with `Parse error`, but `new()` method can't be called and error is undetectable

Open
#96,065 5 comments 0 reactions 0 assignees View on GitHub
discussion topic:gdscript
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions

v4.2.1.stable.official [b09f793f5]
v4.3.stable.official [77dcf97d8]

### System information

Godot v4.2.1.stable

### Issue description

When loading a `.gd` script using the `load()` function in Godot, the function returns a `GDScript` object even if there are parsing errors in the script. This is unexpected because:
- A valid `GDScript` object should always have a `new()` method.
- Despite `loaded.has_method("new")` returning `true`, calling `loaded.new()` results in the error:
```
Invalid call. Nonexistent function 'new' in base 'GDScript'.
```

This issue is problematic because there's no clear way to detect or handle this scenario programmatically. Even with parse errors, the script loads and appears valid according to the checks. The only way to detect that the script has issues is by using `loaded.reload()`, which returns a non-zero value if errors are present. However, relying on this method for error detection is not intuitive or well-documented.

### Expected behavior:
- If there are parsing errors, load() should return null or provide a clear and intuitive way to detect errors.
- A valid GDScript should always have a new() method that can be called without errors.

### Steps to reproduce

Here’s an example of the code and its output in both normal and error scenarios:

### Code:
```gdscript
# res://main.gd
var loaded = load("res://error.gd")
print("loaded: ", loaded)
print("loaded == null: ", loaded == null)
print("loaded is GDScript: ", loaded is GDScript)
print("loaded.has_method('new'): ", loaded.has_method("new"))
print("loaded.new: ", loaded.new)
print("loaded.has_source_code(): ", loaded.has_source_code())
print("loaded.reload(): ", loaded.reload())
loaded.new()
```
```gdscript
# res://error.gd
error
```

### Output with a valid script:
```
loaded:
loaded == null: false
loaded is GDScript: true
loaded.has_method('new'): true
loaded.new: GDScript::new
loaded.has_source_code(): true
loaded.reload(): 0
```

### Output with a script containing parse errors:
```
loaded:
loaded == null: false
loaded is GDScript: true
loaded.has_method('new'): true
loaded.new: GDScript::new
loaded.has_source_code(): true
loaded.reload(): 43
```

### Error encountered:
```
Invalid call. Nonexistent function 'new' in base 'GDScript'.
```

### Steps to reproduce:
1. Use the code provided above to load a script and check its validity.
2. Create a .gd script with syntax errors and attempt to load it.
3. Observe that loaded.has_method("new") returns true, but calling loaded.new() raises an error.
4. Note that loaded.reload() returns a non-zero value, indicating an error that isn't detectable by other checks.

### Minimal reproduction project (MRP)

[gdscript load issue project.zip](https://github.com/user-attachments/files/16739816/gdscript.load.issue.project.zip)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.