Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft

Am using Angular for a sample like Planogram with Palette. Here am getting the above Immer Error, while am updating or upon any changes…
For Initial creation, Add, Delete and move are all fine at initial stage… upon next level getting error, but the purpose of IMMER is to update the model change…

Request your help to guide me on this issue…

  public diagramModelChange = function (changes: go.IncrementalData) {
    if (!changes) return;
    const rvdComp = this;
    this.state = produce(this.state, draft => {
      // set skipsDiagramUpdate: true since GoJS already has this update
      // this way, we don't log an unneeded transaction in the Diagram's undoManager history
      draft.skipsDiagramUpdate = true;
      draft.diagramNodeData = DataSyncService.syncNodeData(
      draft.diagramLinkData = DataSyncService.syncLinkData(changes, draft.diagramLinkData, rvdComp.observedDiagram.model);
      //ADDED removedNodeKeys is to overcome the Error: [Immer] An immer producer returned a new value *and* modified its draft. Either return a new value *or* modify the draft.
      draft.removedNodeKeys = DataSyncService.syncNodeData(
      draft.diagramModelData = DataSyncService.syncModelData(
      // If one of the modified nodes was the selected node used by the inspector, update the inspector selectedNodeData object
      const modifiedNodeDatas = changes.modifiedNodeData;
      // this.latestData = modifiedNodeDatas; //Used to Save and display the list of data below the Plaette's
      if (modifiedNodeDatas && draft.selectedNodeData) {
        for (let i = 0; i < modifiedNodeDatas.length; i++) {
          const mn = modifiedNodeDatas[i];
          const nodeKeyProperty = rvdComp.myDiagramComponent.diagram.model
            .nodeKeyProperty as string;
          if (mn[nodeKeyProperty] === draft.selectedNodeData[nodeKeyProperty]) {
            draft.selectedNodeData = mn;

Could you please show a stack trace when that exception happens?

Hi Walter,

Is upon removing a Device… like below the console output is true for removing the device… and tried to modify the diagramModelChange… but couldn’t

console output is as below:

Device is Removed: true

logger.service.ts:10 ERROR: Error: [Immer] An immer producer returned a new value and modified its draft. Either return a new value or modify the draft. at n (immer.esm.mjs:1:216) at P (immer.esm.mjs:1:2508) at produce (immer.esm.mjs:1:16338) at Function.syncNodeData (gojs-angular.js:708:39) at recording-view-diagr…component.ts:571:31 at produce (immer.esm.mjs:1:16172) at RecordingViewDiagramComponent.diagramModelChange (recording-view-diagr…component.ts:567:25) at RecordingViewDiagramComponent_Template_gojs_diagram_modelChange_36_listener (recording-view-diagr…omponent.html:56:74) at executeListenerWithErrorHandling (core.mjs:14979:16) at Object.wrapListenerIn_markDirtyAndPreventDefault [as next] (core.mjs:15017:22)

error @ logger.service.ts:10
handleError @ custom-error.handler.ts:13
handleError @ core.mjs:10957
executeListenerWithErrorHandling @ core.mjs:14982
wrapListenerIn_markDirtyAndPreventDefault @ core.mjs:15017
next @ Subscriber.js:91
_next @ Subscriber.js:60
next @ Subscriber.js:31
(anonymous) @ Subject.js:34
errorContext @ errorContext.js:19
next @ Subject.js:27
emit @ core.mjs:22427
(anonymous) @ gojs-angular.js:135
_ZoneDelegate.invoke @ zone.js:409
onInvoke @ core.mjs:25548
_ZoneDelegate.invoke @ zone.js:408 @ zone.js:169
run @ core.mjs:25402
component.modelChangedListener @ gojs-angular.js:128 @ go-module.js:1799 @ go-module.js:272
qe @ go-module.js:269
push.1963.t.Xa @ go-module.js:267
push.1963.T.Xa @ go-module.js:693
push.1963.Qk.deleteSelection @ go-module.js:840
push.1963.Qk.doKeyDown @ go-module.js:834
push.1963.Oa.doKeyDown @ go-module.js:307
push.1963.T.doKeyDown @ go-module.js:597
push.1963.T.uA @ go-module.js:628
_ZoneDelegate.invokeTask @ zone.js:443
onInvokeTask @ core.mjs:25535
_ZoneDelegate.invokeTask @ zone.js:442
Zone.runTask @ zone.js:214
ZoneTask.invokeTask @ zone.js:525
invokeTask @ zone.js:1714
globalCallback @ zone.js:1745
globalZoneAwareCallback @ zone.js:1781

And my event listener codes are as below

public ngAfterViewInit() {
    console.log("AT ngAfterViewINIT...")
    if (this.diagram) return;
    this.diagram = this.myDiagramComponent.diagram;
    console.log("AT ngAfterViewINIT... AFTER diagram init")

    if (this.observedDiagram) return;
    this.observedDiagram = this.myDiagramComponent.diagram;
    console.log("AT ngAfterViewINIT...AFTER observedDiagram INIT")

    this.cdr.detectChanges(); // IMPORTANT: without this, Angular will throw ExpressionChangedAfterItHasBeenCheckedError (dev mode only)

    if (this.deviceDiagram) return;
    this.deviceDiagram = this.myDeviceComponent.palette;
    // this.state.devicesNodeData = this.devicesDataArray;
    console.log("AT ngAfterViewINIT...AFTER deviceDiagram-PALETTE INIT")

    if (this.radioDiagram) return;
    this.radioDiagram = this.radioComponent.palette;
    console.log("AT ngAfterViewINIT...AFTER radioDiagram-PALETTE INIT")
    // let d = this.radioComponent.palette.model.nodeDataArray
    console.log("From Radio SERVICE Data is Below: ")

    if (this.lineDiagram) return;
    this.lineDiagram = this.lineComponent.palette;
    console.log("AT ngAfterViewINIT...AFTER lineDiagram-PALETTE INIT")
    console.log("From lineConference SERVICE Data is Below: ")

    if (this.alarmDiagram) return;
    this.alarmDiagram = this.paComponent.palette;
    console.log("AT ngAfterViewINIT...AFTER alarmDiagram-PALETTE INIT")

    const rvdComp: RecordingViewDiagramComponent = this;

      this.myDiagramComponent.diagram.addDiagramListener("ExternalObjectsDropped", function (e) {
      const node = e.diagram.selection.first();
      if (node instanceof go.Node) {

        console.log("Inside addDiagramListener for ExternalObjectsDropped");
        console.log("Now added to the GROUP Diagram are : ");

    this.myDiagramComponent.diagram.addDiagramListener("SelectionDeleted", (e) => {
      console.log("Inside addDiagramListener for SelectionDeleted");

      //  //e.subject is the myDiagram selection
      e.subject.each((n) => {

        if ( {
          console.log("Device is Removed: " +;
        if ( {
          console.log("Conference Line is Removed: " +;
        if ( {
          console.log("Alarm is Removed: " +;
        // if ("AlmSound")) {
        //   console.log("Alarm is Removed: " +"AlmSound"));
        //   rvdComp.alarmDiagram.model.addNodeData(
        //     rvdComp.alarmDiagram.model.copyNodeData(
        //   );
        // }
        if ( {
          console.log("Radio is Removed " +;
  } // end ngAfterViewInit

By the way a quick question Instead of Grouping samples, is there any assign to particular set samples folder…

Thanks for your help…

Thanks for the additional information. We’ll try to investigate it.

I don’t understand your question about “Instead of Grouping samples, is there any assign to particular set samples folder…” Could you please rephrase and explain?

Your call to Immer’s produce function looks OK – the producer is not returning anything but is only modifying the draft object. The same is true for the calls to produce within the gojs-angular component. So I cannot explain why you are getting that exception.

To add on - For this issue is there any link with inspector component or observer/overview diagram or draft.diagramLinkData… As you may notice I am not using the above three compared to angular basic project.

Am trying to do the assignment of devices to User by selection of device nodes & User to a profile / group… While am going through samples, can see the samples for drag and drop with group functions… Am not sure, which sample relates to my requirement. Request your help to give some related sample to fulfill my requirement or an approach

Those three things in the gojs-angular-basic sample are extras that are not required for any diagram app. The Overview is a simple add-on. The Inspector requires more because it’s interactive, so it needs handling of changes to the model.

I don’t know what you mean by: “Am trying to do the assignment of devices to User by selection of device nodes & User to a profile / group” You haven’t shown any screenshots or sketches of what you want, so it’s hard for me to suggest anything.

Hi Walter,
Thanks a lot for the explanation on Inspector and Overview…