FyroxEngine/Fyrox · warning
There is a script instance on a node
Error message
There is a script instance on a node {}, but no message sender. The script won't be correctly destroyed! What it means
When a scene node is destroyed, each of its script instances should receive a DestroyScriptMessage via the engine's message sender so the script can clean up. If the node has a script instance but no message sender is available at that point, Fyrox logs this warning because the script's destructor logic won't run. Resources held by the script (entities, GPU handles, network connections) may leak.
Solutions
- Ensure nodes with scripts are destroyed via the normal Scene API (remove_node) during the update loop so a message sender is present.
- Avoid destroying scripted nodes during graph destruction/shutdown; free resources in the script's on_removed or Drop if teardown-time destruction is unavoidable.
- Review custom code paths that clone/detach ScriptDecompile logic without propagating the sender.
Defensive patterns
Strategy: validation
Prevention
- Only remove scripted nodes via scene.remove_node during the normal update loop.
- Don't destroy nodes during shutdown/teardown; rely on script Drop/on_removed cleanup.
- Free critical resources in on_removed so leaks are bounded if destroy messages are missed.
When it happens
Trigger: Deleting a node (or its subtree) whose Script Decompile path executes while self message sender is None — e.g. destroying nodes during graph teardown phases where the sender was already dropped or never provided.
Common situations: Removing nodes during engine shutdown or inside another script's teardown; constructing/destroying nodes outside the normal update loop where the message sender context is unavailable.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Script message was sent, but there's no receivers. Did you…
- Unable to load script instance of id
- Script instance of id
- An object at index must be returned to a pool it was taken…
- Graphics context is uninitialized!
AI-assisted analysis of FyroxEngine/Fyrox@76c91aad8e (2026-09-10).
Data as JSON: /api/errors/a8a140dfa2866133.
Report an issue: GitHub.
Appendix: source
Thrown at fyrox-impl/src/scene/base.rs:895
/// update tick of the parent graph.
pub fn remove_script(&mut self, index: usize) {
// Send script to the graph to destroy script instances correctly.
if let Some(entry) = self.scripts.get_mut(index) {
entry.should_be_deleted = true;
// We might be in a middle of a script method execution, where script is temporarily
// extracted from the array.
if let Some(script) = entry.take() {
if let Some(senders) = self.senders.as_ref() {
Log::verify(senders.script_message_sender.send(
NodeScriptMessage::DestroyScript {
script,
handle: self.self_handle,
script_index: index,
},
));
} else {
Log::warn(format!(
"There is a script instance on a node {}, but no message sender. \
The script won't be correctly destroyed!",
self.name(),
));
}
}
}
}
/// Removes all assigned scripts from the scene node. The scripts will be removed from
/// first-to-last order an their actual destruction will happen either on the current update tick
/// of the parent graph (if it was removed from some other script) or in the next update tick.
pub fn remove_all_scripts(&mut self) {
let script_count = self.scripts.len();
for i in 0..script_count {
self.remove_script(i);
}
}View on GitHub (pinned to 76c91aad8e)