diff --git a/packages/core/src/Node.ts b/packages/core/src/Node.ts
index 386c37b44c6a67f83a11fa0b044d22d2434fa814..fef42df933390ef3d6b4e8634c7129822980b1fe 100644
--- a/packages/core/src/Node.ts
+++ b/packages/core/src/Node.ts
@@ -1,3 +1,4 @@
+import _ from "lodash";
 import { createHash } from "node:crypto";
 import path from "path";
 import { v4 as uuidv4 } from "uuid";
@@ -141,12 +142,26 @@ export abstract class BaseNode<T extends Metadata = Metadata> {
   }
 
   /**
-   * Used with built in JSON.stringify
-   * @returns
+   * Called by built in JSON.stringify (see https://javascript.info/json)
+   * Properties are read-only as they are not deep-cloned (not necessary for stringification).
+   * @see toMutableJSON - use to return a mutable JSON instead
    */
   toJSON(): Record<string, any> {
     return { ...this, type: this.getType() };
   }
+
+  clone(): BaseNode {
+    return jsonToNode(this.toMutableJSON()) as BaseNode;
+  }
+
+  /**
+   * Converts the object to a JSON representation.
+   * Properties can be safely modified as a deep clone of the properties are created.
+   * @return {Record<string, any>} - The JSON representation of the object.
+   */
+  toMutableJSON(): Record<string, any> {
+    return _.cloneDeep(this.toJSON());
+  }
 }
 
 /**
diff --git a/packages/core/src/indices/vectorStore/VectorStoreIndex.ts b/packages/core/src/indices/vectorStore/VectorStoreIndex.ts
index b588b34eea6bfc2783774530e61aeda4d1d3eab1..278209f2cf16f9e1c9d5a2c75721e6a67fb5ca97 100644
--- a/packages/core/src/indices/vectorStore/VectorStoreIndex.ts
+++ b/packages/core/src/indices/vectorStore/VectorStoreIndex.ts
@@ -4,7 +4,6 @@ import {
   ImageNode,
   MetadataMode,
   ObjectType,
-  jsonToNode,
   splitNodesByType,
 } from "../../Node";
 import { BaseQueryEngine, RetrieverQueryEngine } from "../../QueryEngine";
@@ -278,7 +277,7 @@ export class VectorStoreIndex extends BaseIndex<IndexDict> {
         type === ObjectType.INDEX ||
         type === ObjectType.IMAGE
       ) {
-        const nodeWithoutEmbedding = jsonToNode(nodes[i].toJSON());
+        const nodeWithoutEmbedding = nodes[i].clone();
         nodeWithoutEmbedding.embedding = undefined;
         this.indexStruct.addNode(nodeWithoutEmbedding, newIds[i]);
         this.docStore.addDocuments([nodeWithoutEmbedding], true);
diff --git a/packages/core/src/storage/vectorStore/utils.ts b/packages/core/src/storage/vectorStore/utils.ts
index cf9e5728e97cc4b00f4433e7acb4224061e0759f..a20dbf7e69e005b9f0f887ab69eec291da652825 100644
--- a/packages/core/src/storage/vectorStore/utils.ts
+++ b/packages/core/src/storage/vectorStore/utils.ts
@@ -1,4 +1,3 @@
-import _ from "lodash";
 import { BaseNode, jsonToNode, Metadata, ObjectType } from "../../Node";
 
 const DEFAULT_TEXT_KEY = "text";
@@ -17,7 +16,7 @@ export function nodeToMetadata(
   textField: string = DEFAULT_TEXT_KEY,
   flatMetadata: boolean = false,
 ): Metadata {
-  const { metadata, embedding, ...rest } = _.cloneDeep(node.toJSON());
+  const { metadata, embedding, ...rest } = node.toMutableJSON();
 
   if (flatMetadata) {
     validateIsFlat(metadata);