diff --git a/.changeset/empty-bugs-occur.md b/.changeset/empty-bugs-occur.md
new file mode 100644
index 000000000..5eecb5480
--- /dev/null
+++ b/.changeset/empty-bugs-occur.md
@@ -0,0 +1,5 @@
+---
+"@browserbasehq/stagehand": patch
+---
+
+wrap page.evaluate to make sure we have injected browser side scripts before calling them
diff --git a/evals/deterministic/tests/page/addInitScript.test.ts b/evals/deterministic/tests/page/addInitScript.test.ts
index 56be8ef41..835b12be6 100644
--- a/evals/deterministic/tests/page/addInitScript.test.ts
+++ b/evals/deterministic/tests/page/addInitScript.test.ts
@@ -37,4 +37,32 @@ test.describe("StagehandPage - addInitScript", () => {
 
     await stagehand.close();
   });
+
+  test("checks if init scripts are re-added and available even if they've been deleted", async () => {
+    const stagehand = new Stagehand(StagehandConfig);
+    await stagehand.init();
+
+    const page = stagehand.page;
+    await page.goto(
+      "https://browserbase.github.io/stagehand-eval-sites/sites/aigrant/",
+    );
+
+    // delete the __stagehandInjected flag, and delete the
+    // getScrollableElementXpaths function
+    await page.evaluate(() => {
+      delete window.getScrollableElementXpaths;
+      delete window.__stagehandInjected;
+    });
+
+    // attempt to call the getScrollableElementXpaths function
+    // which we previously deleted. page.evaluate should realize
+    // its been deleted and re-inject it
+    const xpaths = await page.evaluate(() => {
+      return window.getScrollableElementXpaths();
+    });
+
+    await stagehand.close();
+    // this is the only scrollable element on the page
+    expect(xpaths).toContain("/html");
+  });
 });
diff --git a/lib/StagehandPage.ts b/lib/StagehandPage.ts
index 6d2aad423..557c95cfb 100644
--- a/lib/StagehandPage.ts
+++ b/lib/StagehandPage.ts
@@ -31,9 +31,11 @@ import {
   StagehandDefaultError,
 } from "../types/stagehandErrors";
 import { StagehandAPIError } from "@/types/stagehandApiErrors";
+import { scriptContent } from "@/lib/dom/build/scriptContent";
 
 export class StagehandPage {
   private stagehand: Stagehand;
+  private rawPage: PlaywrightPage;
   private intPage: Page;
   private intContext: StagehandContext;
   private actHandler: StagehandActHandler;
@@ -60,6 +62,7 @@ export class StagehandPage {
     api?: StagehandAPI,
     waitForCaptchaSolves?: boolean,
   ) {
+    this.rawPage = page;
     // Create a proxy to intercept all method calls and property access
     this.intPage = new Proxy(page, {
       get: (target: PlaywrightPage, prop: keyof PlaywrightPage) => {
@@ -117,6 +120,35 @@ export class StagehandPage {
     }
   }
 
+  private async ensureStagehandScript(): Promise<void> {
+    try {
+      const injected = await this.rawPage.evaluate(
+        () => !!window.__stagehandInjected,
+      );
+
+      if (injected) return;
+
+      const guardedScript = `if (!window.__stagehandInjected) { \
+window.__stagehandInjected = true; \
+${scriptContent} \
+}`;
+
+      await this.rawPage.addInitScript({ content: guardedScript });
+      await this.rawPage.evaluate(guardedScript);
+    } catch (err) {
+      this.stagehand.log({
+        category: "dom",
+        message: "Failed to inject Stagehand helper script",
+        level: 1,
+        auxiliary: {
+          error: { value: (err as Error).message, type: "string" },
+          trace: { value: (err as Error).stack, type: "string" },
+        },
+      });
+      throw err;
+    }
+  }
+
   private async _refreshPageFromAPI() {
     if (!this.api) return;
 
@@ -217,7 +249,7 @@ export class StagehandPage {
 
   async init(): Promise<StagehandPage> {
     try {
-      const page = this.intPage;
+      const page = this.rawPage;
       const stagehand = this.stagehand;
 
       // Create a proxy that updates active page on method calls
@@ -225,6 +257,24 @@ export class StagehandPage {
         get: (target: PlaywrightPage, prop: string | symbol) => {
           const value = target[prop as keyof PlaywrightPage];
 
+          // Inject-on-demand for evaluate
+          if (
+            prop === "evaluate" ||
+            prop === "evaluateHandle" ||
+            prop === "$eval" ||
+            prop === "$$eval"
+          ) {
+            return async (...args: unknown[]) => {
+              this.intContext.setActivePage(this);
+              // Make sure helpers exist
+              await this.ensureStagehandScript();
+              return (value as (...a: unknown[]) => unknown).apply(
+                target,
+                args,
+              );
+            };
+          }
+
           // Handle enhanced methods
           if (prop === "act" || prop === "extract" || prop === "observe") {
             if (!this.llmClient) {
diff --git a/lib/dom/global.d.ts b/lib/dom/global.d.ts
index 742c15433..aff82fa29 100644
--- a/lib/dom/global.d.ts
+++ b/lib/dom/global.d.ts
@@ -3,6 +3,7 @@ import { StagehandContainer } from "./StagehandContainer";
 export {};
 declare global {
   interface Window {
+    __stagehandInjected?: boolean;
     chunkNumber: number;
     showChunks?: boolean;
     processDom: (chunksSeen: Array<number>) => Promise<{
diff --git a/lib/index.ts b/lib/index.ts
index a12b63a72..735647fb3 100644
--- a/lib/index.ts
+++ b/lib/index.ts
@@ -715,8 +715,14 @@ export class Stagehand {
       await this.page.setViewportSize({ width: 1280, height: 720 });
     }
 
+    const guardedScript = `
+  if (!window.__stagehandInjected) {
+    window.__stagehandInjected = true;
+    ${scriptContent}
+  }
+`;
     await this.context.addInitScript({
-      content: scriptContent,
+      content: guardedScript,
     });
 
     this.browserbaseSessionID = sessionId;