Skip to content

Enable client logs like server logs in sandbox - #187

Closed
ctate wants to merge 2 commits into
mainfrom
agent/2025-10-25T16-56-44-k3ktcHG_kelH
Closed

ctate wants to merge 2 commits into
mainfrom
agent/2025-10-25T16-56-44-k3ktcHG_kelH

Conversation

@ctate

@ctate ctate commented Oct 25, 2025

Copy link
Copy Markdown
Collaborator

No description provided.

@vercel

vercel Bot commented Oct 25, 2025

Copy link
Copy Markdown
Contributor

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Preview Comments Updated (UTC)
coding-agent-platform Ready Ready Preview Comment Oct 25, 2025 5:02pm

Comment on lines +68 to +74
return {
info,
command,
error,
success,
flush,
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hook returns a new object literal on every render, causing the object reference to change even though the contained functions are memoized. This will cause the clientLogger dependency in task-page-client.tsx to change on every render, leading to the "Task page loaded in browser" log being recorded multiple times instead of just once.

View Details
📝 Patch Details
diff --git a/lib/hooks/use-client-logger.ts b/lib/hooks/use-client-logger.ts
index 365481f..b754fca 100644
--- a/lib/hooks/use-client-logger.ts
+++ b/lib/hooks/use-client-logger.ts
@@ -1,4 +1,4 @@
-import { useEffect, useRef, useCallback } from 'react'
+import { useEffect, useRef, useCallback, useMemo } from 'react'
 import { createClientLogger, ClientLogger } from '@/lib/utils/client-logger'
 
 /**
@@ -65,11 +65,11 @@ export function useClientLogger(taskId: string | null | undefined) {
     }
   }, [loggerRef])
 
-  return {
+  return useMemo(() => ({
     info,
     command,
     error,
     success,
     flush,
-  }
+  }), [info, command, error, success, flush])
 }

Analysis

Object reference changes on every render causes repeated logging in task-page-client

What fails: useClientLogger() returns a new object literal on every render, causing the clientLogger dependency in task-page-client.tsx to change reference every render, which triggers the useEffect to run repeatedly instead of once.

How to reproduce:

// In task-page-client.tsx:
const clientLogger = useClientLogger(taskId)
useEffect(() => {
  if (task && clientLogger) {
    clientLogger.info('Task page loaded in browser')  // Logs multiple times
  }
}, [task, clientLogger])  // clientLogger reference changes every render

This causes the "Task page loaded in browser" message to be logged to the server multiple times when the page loads, instead of just once as intended.

Expected behavior: Per React's useEffect dependency documentation, dependency arrays use reference equality. React's official guidance states that when an object needs to remain stable between renders to prevent Effects from firing excessively, it should be wrapped in useMemo.

Fix: Wrap the returned object in useMemo to maintain referential equality across renders when the contained callback functions haven't changed:

  • Added useMemo to imports
  • Wrapped the return statement with useMemo and dependencies [info, command, error, success, flush]
  • Since all callbacks depend only on the stable loggerRef, the memoized object maintains identity across renders

@ctate ctate closed this Oct 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant