Skip to content

Conversation

@AbanoubGhadban
Copy link
Collaborator

@AbanoubGhadban AbanoubGhadban commented Feb 12, 2026

Summary

Closes #2394

When RSC support is enabled, components without 'use client' are silently classified as server components. If an interactive component (hooks, class components, event handlers) is missing this directive, it crashes at runtime with error messages that never mention the actual cause. This PR improves error messages at multiple layers:

  • Runtime (server bundle): wrapServerComponentRenderer now catches the streaming context assertion failure and re-throws with the component name, suggesting either adding 'use client' or using stream_react_component instead of react_component
  • Runtime (client bundle): All error messages in the client wrapper now include the component name and 'use client' guidance
  • Runtime (generic): throwRailsContextMissingEntries now lists missing 'use client' as the most common cause instead of only suggesting config changes
  • Build-time heuristic: The packs generator scans files classified as server components for client-only patterns (hooks, event handlers, extends Component) and emits a Rails.logger.warn with specific API names found
  • Build-time summary: Prints RSC component classification (server vs client) during pack generation
  • Generated file comments: Server component pack files now explain why the component was classified as a server component and how to fix it

Before

Rails context does not have server side getRSCPayloadStream and addPostSSRHook functions.
Please ensure:
1. You are using a compatible version of react_on_rails_pro
2. Server components support is enabled by setting:
   ReactOnRailsPro.configuration.enable_rsc_support = true

After

Server component 'HelloWorld' cannot be rendered in this context.

This usually means one of:
1. 'HelloWorld' uses client-side features (hooks, event handlers, class components)
   but is missing the "use client" directive at the top of its file.
   Add '"use client";' as the first line to register it as a client component.
2. 'HelloWorld' is rendered with react_component() instead of stream_react_component().
   Server components require the streaming render helper.

Test plan

  • TypeScript builds: both react-on-rails and react-on-rails-pro compile cleanly
  • JS tests: 112 passed (react-on-rails), 8 passed (react-on-rails-pro including 4 RSC suites)
  • Ruby tests: 81 passed (packs_generator_spec) — updated 2 test expectations for the new generated file comments
  • ESLint: all changed files pass lint
  • Rubocop: packs_generator.rb passes with no offenses

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Server component error messages now display component names for easier debugging.
    • Added warnings when components use client-side APIs without proper configuration directives.
  • Bug Fixes

    • Improved error handling for missing configuration contexts with clearer guidance.
  • Chores

    • Removed unused dependencies and simplified project configuration.

AbanoubGhadban and others added 2 commits February 12, 2026 16:41
Remove leftover yalc-era pnpm-workspace.yaml from the Pro dummy app
that caused pnpm to treat it as an isolated workspace root, preventing
webpack binary resolution from the repo root node_modules/.bin/.

Remove pinned @pmmmwh/[email protected] from dummy's
devDependencies that conflicted with Shakapacker's 0.5.17 at root,
causing the react-refresh loader to be applied twice in dev server mode.

Fixes #2399

Co-Authored-By: Claude Opus 4.6 <[email protected]>
…ent' with RSC enabled

When RSC support is enabled and a component is missing the 'use client'
directive, the packs generator silently registers it as a server component.
This causes cryptic runtime errors that never mention 'use client' as the
root cause. This commit improves error messages at multiple layers:

- Enrich wrapServerComponentRenderer (server & client) to include the
  component name and suggest adding 'use client' or using
  stream_react_component instead of react_component
- Improve throwRailsContextMissingEntries generic error to mention
  'use client' as the most common cause
- Add build-time heuristic warning in packs generator that detects
  client-only APIs (hooks, event handlers, class components) in files
  classified as server components
- Log RSC component classification summary during pack generation
- Add explanatory comments in generated server component pack files

Closes #2394

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 12, 2026

Walkthrough

The changes enhance error messaging and build-time detection for interactive components missing the 'use client' directive with RSC enabled. Component names are threaded through the server component registration pipeline, error messages are enriched with component context, and the packs generator introduces heuristic detection of client-side APIs in server components with warning feedback.

Changes

Cohort / File(s) Summary
Server Component Wrapping Pipeline
packages/react-on-rails-pro/src/registerServerComponent/client.tsx, packages/react-on-rails-pro/src/registerServerComponent/server.tsx, packages/react-on-rails-pro/src/wrapServerComponentRenderer/client.tsx, packages/react-on-rails-pro/src/wrapServerComponentRenderer/server.tsx
Thread component name through registration and wrapping functions. Update signatures to accept optional componentName parameter and incorporate it into error messages. Wrap context assertion in try/catch to provide component-aware error guidance.
Error Message Improvements
packages/react-on-rails/src/types/index.ts
Enhance throwRailsContextMissingEntries error message to address practical causes: missing "use client" directive, incorrect render helper usage, and RSC enablement requirement.
Pack Generation & Detection
react_on_rails/lib/react_on_rails/packs_generator.rb, react_on_rails/spec/dummy/spec/packs_generator_spec.rb
Add RSC classification summary logging and client-side API detection. Introduce CLIENT_API_PATTERN heuristic and warn_if_likely_client_component helper to detect components using hooks/events without "use client" directive. Update test expectations for generated comment headers.
Dependency Cleanup
react_on_rails_pro/spec/dummy/package.json, react_on_rails_pro/spec/dummy/pnpm-workspace.yaml
Remove unused devDependency @pmmmwh/react-refresh-webpack-plugin and workspace configuration from pnpm manifest.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Poem

🐰 A rabbit hops through warnings bright,
Threading names through RSC's flight,
"Use client, dear," the errors now say,
Catching missing directives by day,
Build-time detection saves the way! 🌟

🚥 Pre-merge checks | ✅ 3 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning Most changes are directly scoped to improving error messages for missing 'use client' directives. However, two changes appear tangentially out-of-scope: removing a devDependency and pnpm workspace configuration in the Pro dummy app, which relate to fixing issue #2399 rather than #2394. Consider isolating the dummy app dependency fixes (package.json and pnpm-workspace.yaml removals) into a separate PR focused on #2399, keeping this PR narrowly scoped to the error message improvements for #2394.
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title clearly and concisely summarizes the main objective: improving error messages when components lack the 'use client' directive with RSC enabled. It directly reflects the primary changes throughout the codebase.
Linked Issues check ✅ Passed All three suggested improvements from issue #2394 are implemented: build-time detection warnings via client-side API pattern scanning in packs_generator.rb, enhanced runtime error messages in wrapServerComponentRenderer that mention 'use client' as a cause, and RSC classification logging with component comments for build-time guidance.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 2394-rsc-missing-use-client-error-messages

No actionable comments were generated in the recent review. 🎉

🧹 Recent nitpick comments
packages/react-on-rails-pro/src/wrapServerComponentRenderer/server.tsx (1)

54-64: Consider preserving the original error as cause for better debugging.

The original error's stack trace is lost when re-throwing. Using the cause option preserves the full chain, which aids debugging in development.

🔧 Suggested improvement
       throw new Error(
         `Server component '${displayName}' cannot be rendered in this context.\n\n` +
           `This usually means one of:\n` +
           `1. '${displayName}' uses client-side features (hooks, event handlers, class components)\n` +
           `   but is missing the "use client" directive at the top of its file.\n` +
           `   Add '"use client";' as the first line to register it as a client component.\n` +
           `2. '${displayName}' is rendered with react_component() instead of stream_react_component().\n` +
-          `   Server components require the streaming render helper.${originalMessage}`,
+          `   Server components require the streaming render helper.${originalMessage}`,
+        { cause: e },
       );

Based on learnings: "When handling errors in 'node_package/src/ReactOnRailsRSC.ts', include the error stack in error messages in development and test environments to aid debugging."

react_on_rails/lib/react_on_rails/packs_generator.rb (1)

154-171: Heuristic pattern detection looks good; minor note on double file read.

The CLIENT_API_PATTERN regex and warning logic are well-designed for a heuristic — the comment at lines 154-156 correctly notes that false positives in comments are acceptable.

Note that warn_if_likely_client_component re-reads the file that client_entrypoint? (line 177 condition) already read. If this becomes a concern, the file content could be read once and passed to both checks — but this is fine for a build-time tool.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link

greptile-apps bot commented Feb 12, 2026

Greptile Overview

Greptile Summary

This PR significantly improves the developer experience when React Server Components (RSC) support is enabled by providing actionable error messages at multiple layers (build-time and runtime) when interactive components are missing the 'use client' directive.

Key Improvements

  • Runtime error handling: wrapServerComponentRenderer now catches context assertion failures and provides clear, component-specific error messages explaining the most likely causes (missing 'use client' or using wrong render helper)
  • Build-time warnings: PacksGenerator scans server components for client-only patterns (hooks, event handlers, class components) and emits warnings when detected
  • Generated file documentation: Server component pack files now include explanatory comments about why they were classified as server components
  • Build-time visibility: Logs RSC classification summary showing which components are server vs client

Changes Made

The error message improvements span TypeScript (client/server wrappers), Ruby (packs generator), and test updates. Additionally, unused dependencies were cleaned up (@pmmmwh/react-refresh-webpack-plugin and pnpm-workspace.yaml).

Implementation Quality

  • Error messages are contextual and actionable
  • Heuristic pattern matching for client APIs is intentionally permissive (accepting false positives in comments) since it's a warning, not an error
  • Tests have been updated to reflect new generated file comments
  • All tests pass according to the PR description

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • Score of 5 reflects comprehensive testing (TypeScript builds, JS tests with 120 passing, Ruby tests with 81 passing, ESLint, Rubocop), focused scope (error message improvements only), and defensive implementation (try-catch blocks preserve original errors, heuristic warnings are non-blocking)
  • No files require special attention

Important Files Changed

Filename Overview
packages/react-on-rails-pro/src/wrapServerComponentRenderer/server.tsx Added componentName parameter and try-catch for better error messages when server components are missing 'use client'
packages/react-on-rails-pro/src/wrapServerComponentRenderer/client.tsx Added componentName parameter to improve error messages with component context
packages/react-on-rails/src/types/index.ts Reordered error message to prioritize missing 'use client' as most common cause
react_on_rails/lib/react_on_rails/packs_generator.rb Added build-time heuristic warnings, RSC classification summary logging, and generated file comments

Sequence Diagram

sequenceDiagram
    participant User as Developer
    participant Rails as Rails App
    participant PackGen as PacksGenerator
    participant Client as Client Bundle
    participant Server as Server Bundle
    participant Wrapper as wrapServerComponent

    Note over User,Wrapper: Build Time
    User->>Rails: Create component without 'use client'
    Rails->>PackGen: bundle exec rake generate_packs
    PackGen->>PackGen: Scan for 'use client' directive
    alt Missing 'use client' + uses hooks/events
        PackGen->>Rails: Rails.logger.warn (CLIENT_API_PATTERN matched)
    end
    PackGen->>Client: Generate pack with registerServerComponent
    Note over Client: Comment added explaining server component classification

    Note over User,Wrapper: Runtime - Server Side
    User->>Rails: Request page with component
    Rails->>Server: stream_react_component('Component')
    Server->>Wrapper: wrapServerComponentRenderer called
    Wrapper->>Wrapper: assertRailsContextWithServerStreamingCapabilities
    alt Missing railsContext capabilities
        Wrapper->>Rails: Throw error with component name + guidance
        Rails->>User: Error: "Component 'X' cannot be rendered...<br/>Add 'use client' or use stream_react_component()"
    end

    Note over User,Wrapper: Runtime - Client Side
    User->>Client: Hydrate component
    Client->>Wrapper: wrapServerComponentRenderer (client version)
    alt Missing domNodeId
        Wrapper->>User: Error: "No domNodeId for 'Component'"
    else Missing railsContext
        Wrapper->>User: Error: "No railsContext for 'Component'<br/>Add 'use client' if component uses hooks/events"
    end
Loading

@github-actions
Copy link
Contributor

size-limit report 📦

Path Size
react-on-rails/client bundled (gzip) 62.5 KB (0%)
react-on-rails/client bundled (gzip) (time) 62.5 KB (0%)
react-on-rails/client bundled (brotli) 53.71 KB (0%)
react-on-rails/client bundled (brotli) (time) 53.71 KB (0%)
react-on-rails-pro/client bundled (gzip) 63.5 KB (0%)
react-on-rails-pro/client bundled (gzip) (time) 63.5 KB (0%)
react-on-rails-pro/client bundled (brotli) 54.67 KB (0%)
react-on-rails-pro/client bundled (brotli) (time) 54.67 KB (0%)
registerServerComponent/client bundled (gzip) 127.21 KB (+0.08% 🔺)
registerServerComponent/client bundled (gzip) (time) 127.21 KB (+0.08% 🔺)
registerServerComponent/client bundled (brotli) 61.65 KB (+0.23% 🔺)
registerServerComponent/client bundled (brotli) (time) 61.65 KB (+0.23% 🔺)
wrapServerComponentRenderer/client bundled (gzip) 121.72 KB (+0.09% 🔺)
wrapServerComponentRenderer/client bundled (gzip) (time) 121.72 KB (+0.09% 🔺)
wrapServerComponentRenderer/client bundled (brotli) 56.65 KB (+0.12% 🔺)
wrapServerComponentRenderer/client bundled (brotli) (time) 56.65 KB (+0.12% 🔺)

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.

Improve error messages when interactive component is missing 'use client' with RSC enabled

1 participant