-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Description
Check for duplicates
- I have searched for similar issues before opening a new one.
Description
When loading workspace XML that contains a block connected to an input with an incompatible type, the child block becomes completely invisible. It still exists in the workspace data but has no visual representation.
Expected behavior
When a connection fails due to a type mismatch during XML loading, the child block should still be visible on the workspace as a disconnected/orphan block
Actual behavior
The block exists in the workspace's internal state but is never visually rendered. It becomes a "ghost block".
The ghost blocks are still returned by workspace.getTopBlocks() and pass isEnabled() checks. In our application, we have a validation step that checks for detached enabled blocks:
const topLevelBlocks = workspace
.getTopBlocks(false)
.filter((block) => !block.getInheritedDisabled() && block.isEnabled());
if (topLevelBlocks.length > 1) {
return ["Detached, enabled blocks not supported!"];
}
This validation fires because the ghost blocks exist as enabled top-level blocks in the data model but the user cannot see them on the workspace to fix or remove them. The user is told they have detached enabled blocks, but these blocks are invisible.
We later built a custom post-load step that walks all connections, checks type compatibility, and manually disconnects mismatched blocks. However, even with this workaround, the disconnected blocks do not become visible on the same load, they remain as ghost blocks. They only become visible orphans after the workspace is re-saved and triggered the workspace to reload again and we can't explicitly use this as workaround for our users as this will cause bigger problem if the input with detached values is mark as required input.
How we discovered this
In our application, users can change a data type on one tab (e.g., from Long to Int) while a visual programming editor (where blockly is used to config behavior) on another tab is closed. When the editor tab reopens, the saved XML is loaded, and any blocks that were previously valid but are
now type-incompatible silently vanish.
Version: 12.3.1
Reproduction steps
- Define two block types with different types:
- Block A: has a value input that accepts "Int"
- Block B: has an output of type "Long"
- Create workspace XML where Block B is nested inside Block A's value input:
Priority
Its not a app-crashing kind of issue. But its an important one to be addressed when possible. We don't have any workaround to address right now. And it is causing confusion.
Stack trace
Screenshots
No response
Browsers
Chrome desktop