Fix Error: Event handlers cannot be passed to Client Component props.
Note:
The Challenge: [–more–]
⨯ Error: Event handlers cannot be passed to Client Component props.
<button onClick={function onClick} className=... children=...>
^^^^^^^^^^^^^^^^^^
If you need interactivity, consider converting part of this to a Client Component.
at stringify (<anonymous>)
at stringify (<anonymous>)
digest: "3510721672"
I encountered a persistent and misleading error in a Next.js 14 application: Error: Event handlers cannot be passed to Client Component props. The error occurred when navigating to a dynamic user profile page (/app/[username]), but the stack trace was generic and didn’t point to a specific component.
The Debugging Journey:
The initial debugging process was a long chase, as the error message suggested a common but incorrect root cause in this case. My attempts included:
- Standard Checks: Ensured all components using client-side hooks (like useState, useEffect, useRouter) were correctly marked with the “use client”; directive. This fixed several minor bugs but not the main error.
- Refactoring: Broke down large client components into smaller, more manageable ones, thinking the issue was related to component complexity. This improved code quality but didn’t solve the problem.
- Data Fetching: Investigated and fixed an unrelated SSL error in the server-side fetch call within the page.js file.
- Cache Clearing: Completely cleared the Next.js cache (.next directory) to rule out stale build artifacts.
- The Breakthrough: After exhausting all conventional methods, I decided to investigate the project’s recent git history to isolate the exact commit that introduced the bug.
The Root Cause & The Solution:
The git show <commit_hash> command revealed that the problematic commit had introduced a new file: app/[username]/not-found.js.
This file is a special Next.js convention for rendering a 404 page for the /[username] route. The file contained a button with an onClick handler to allow users to go back. However, like all components in the App Router, it was a Server Component by default.
The error was only triggered when visiting a non-existent user profile, which is why it was so hard to trace. The server-side rendering process for the 404 page failed because it encountered an onClick handler, which is client-side interactivity.
The fix was a simple, one-line change: adding “use client”; to the top of app/[username]/not-found.js.
Key Takeaways:
- The error isn’t always on the “happy path”: The bug was in an error-handling file (not-found.js), not the main page component. It’s crucial to debug edge cases and special files.
- Next.js conventions are still components: Special files like layout.js, error.js, and not-found.js must adhere to the same Server/Client Component rules as any other component.
git
is a powerful debugging tool: When you’re stuck, using git log, git show, or git bisect to trace the history of a bug can be the most effective way to find its origin.- Generic errors can be misleading: The error message pointed to a symptom, not the cause. The real issue was a server component trying to render client-side interactive elements.