Node showing incorrectly after undoing the drag and drop action that added it

I have a very strange issue.
I have a diagram with nodes that use different templates. I am dragging and dropping items into this diagram. UndoManager is enabled.
I move one of the nodes in the diagram, then I drag and drop a new node into the diagram, then I undo both actions, then I redo both actions, then I undo only the drag and drop and instead of the item disappearing I still see it but with no data, just like the plain template.
I checked at this point the undoManager history and didn’t see anything unsusual. I checked the number of nodes in the diagram and it was the correct number (as if the node that was suppose to be removed was fully removed.) I checked diagram.model.nodeDataArray and this also had the correct number of items. On the other hand when calling diagram.makeImage I do see the corrupted node that should have been removed.
What could be the cause of this?

Exactly which version of GoJS are you using? go.Diagram.version

How is your Diagram initialized?

The version is 2.3.5
By how the diagram is initialized you mean this?
`const diagram = goMake(go.Diagram, ‘model-designer-canvas’, {

	'undoManager.isEnabled': true,
	'animationManager.isEnabled': false,
	LayoutCompleted: function (e) {
		e.diagram.moveParts(e.diagram.nodes, new go.Point(0, 0), false);
	},
	layout: goMake(go.LayeredDigraphLayout, {
		direction: 90,
		layeringOption: go.LayeredDigraphLayout.LayerLongestPathSource,
		isInitial: false,
		isOngoing: false,
		layerSpacing: 50,
		columnSpacing: 50,
		setsPortSpots: false,
	}),...`

There are a lot of properties and functions that are set at initialization and also later…

I was interested in the version number and what customizations you had done of layout and the DraggingTool and if you were using the “svg” renderer. If you are using SVG in any capacity, I do recommend updating to the latest, 2.3.11.

I assume the “LayoutCompleted” listener is to make sure all nodes are aligned to a grid.

Have you made any customizations of the DraggingTool, either by setting its properties, overriding its methods, or subclassing?

How are you calling Diagram.makeImage?

We are not using svg rendering.
I called Diagram.makeImage to try and understand the issue better from console, not as part of the code.
Here are som customizations of draggingTool

'draggingTool.computeEffectiveCollection': function (
			parts,
			options
		): go.Map<go.Part, go.DraggingInfo> {
			const all = new go.List();
			parts.each((p) => {
				all.add(p);
				if (p.containingGroup !== null && !(p instanceof go.Link)) {
					all.add(p.containingGroup);
				} else if (p.data.hasComment) {
					const relatedComment = modelDesignerHelper.findRelatedComment(p);
					const diagram = p.diagram;
					diagram.commit(() => {
						relatedComment.movable = true;
					}, goTransactions.updateRelatedCommentLocation);
					all.add(relatedComment);
				}
			});
			return go.DraggingTool.prototype.computeEffectiveCollection.call(this, all, options);
		},
		'draggingTool.isCopyEnabled': false,
diagram.toolManager.draggingTool.isGridSnapEnabled = true;
diagram.toolManager.draggingTool.gridSnapCellSize = new go.Size(16, 16);

I don’t know what might be going on. I do remember that a similar bug existed a while ago, but I thought it was just with “svg” rendering. I still recommend updating to 2.3.11 as a cheap thing to try to see if the problem goes away.

Is there any way that we can reproduce the problem?

Updating the version can be complex for me.
Do you have any recommendation how I can debug this to try and understand where the issue is?

Even if you don’t change your whole environment to update to a new baselevel of GoJS, you could experimentally use the latest version of the library.

If you comment out your override of DraggingTool.computeEffectiveCollection, do things work better? Did one of the nodes that you drag-and-dropped have a “related comment”?

How can I experimentally use the latest version?
Commenting out the override of DraggingTool.computeEffectiveCollection did not make any difference.
Are there any properties that can give me an indication of what’s happening? How come I see an item in the graph that is not part of the nodeDataArray?

I was suggesting simply replacing the go.js or go-module.js file wherever you are importing it from.

Because your override of DraggingTool.computeEffectiveCollection performed its own transaction, it was a possibility for messing something up, although I thought it was a long shot. Still, it’s good to simplify as much as possible in order to reproduce the bug.

Seeing a small screenshot of the problem would be helpful.

So the ghost that you are seeing looks like an instance of a node template of the target diagram, yes? Is it of the expected node template for the kind of data that you were dragging? But it looks like its bindings haven’t been evaluated?

I’m curious about what that node template is and any other customizations you have done for Diagram or Palette behavior.

OK, so you have already checked myDiagram.nodes.count and myDiagram.model.nodeDataArray.length.

I tried updating the version but it made no difference.

yes

This is the template for the item in the diagram (the target where the item is dropped.)

goMake(
		go.Node,
		go.Panel.Auto,
		{
			name: 'item-node',
			locationSpot: go.Spot.TopLeft,
			locationObjectName: 'inner-shape',
			resizable: false,
			isShadowed: true,
			shadowOffset: new go.Point(0, 2),
			selectionAdorned: false,
			selectionObjectName: 'node-item-container',
			mouseEnter: (_e: go.InputEvent, obj: go.Part) => {
				...
			},
			mouseLeave: (_e: go.InputEvent, obj: go.Part) => {
				if (!obj.isSelected) {
					obj.shadowOffset = new go.Point(0, 2);
					obj.shadowBlur = defaultShadow.blur;
					obj.shadowColor = defaultShadow.color;
				}
			},
			mouseDragEnter: (_e: go.InputEvent, thisObj: go.Node) => {
				...
},
			mouseDragLeave: (_e: go.InputEvent, thisObj: go.Node) => {
				...
		},
		new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
		new go.Binding('deletable', 'deletable'),
		new go.Binding('movable', 'movable'),
		new go.Binding('selectable', 'selectable'),
		new go.Binding('isSelected', 'isSelected').makeTwoWay(),
...
		

This is the template for the item in the palette before we drag it into the diagram

goMake(
		go.Node,
		go.Panel.Auto,
		{
			name: 'model-palette-item-node',
			resizable: false,
			isShadowed: true,
			shadowOffset: new go.Point(0, 2),
			selectionAdorned: false,
			selectionObjectName: 'node-item-container',
			cursor: hasNoPermission ? 'default' : 'grab',
		},
		{
			mouseEnter: (_e: go.InputEvent, obj: go.Part) => {
				...
			},
			mouseLeave: (_e: go.InputEvent, obj: go.Part) => {
				...
		},
		new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
		new go.Binding('movable', 'movable'),
		new go.Binding('selectable', 'selectable'),
		new go.Binding('isSelected', 'isSelected').makeTwoWay(),
		new go.Binding('isHighlighted', 'isHighlighted').makeTwoWay(),
		new go.Binding('shadowBlur', 'isSelected', (selected) =>
			selected ? activeShadow.blur : defaultShadow.blur
		).ofObject(),
		new go.Binding('shadowColor', 'isSelected', (selected) =>
			selected ? activeShadow.color : defaultShadow.color
		).ofObject(),
    ...

Here is the palette that contains the items I’m dragging from.

goMake(go.Palette, 'components-palette', {
		nodeTemplateMap: entityPaletteElements(),
		layout: goMake(go.GridLayout, {
			cellSize: new go.Size(1, 1),
			spacing: new go.Size(8, 8),
			comparer: helper.keyCompare,
		}),
		'animationManager.isEnabled': false,
		allowZoom: false,
		maxSelectionCount: Infinity,
	})

This issue does not happen with other templates. Though I went over the templates and didn’t find anything suspicious.

I have already checked myDiagam.nodes.count and myDiagram.model.nodeDataArray and both have correct values as if the item was removed from the diagram by the undo.

Those mouse… event handlers – what do they do?

Some visual changes.
obj.shadowOffset = new go.Point(0, 2);
obj.shadowBlur = defaultShadow.blur;
obj.shadowColor = defaultShadow.color;

Yes, I saw that, but I don’t know what the other event handlers do – you have elided the code there. I suppose if they only affect HTML outside of the diagram, it shouldn’t matter.

By the way, I have tried to reproduce the problem in our samples, but I have not had any success (failure?).