facebook/react · error · Error

Cannot have both "use client" and "use server" directives in

Error message

Cannot have both "use client" and "use server" directives in the same file.

What it means

react-server-dom-unbundled's node-register hook wraps module.compile to detect RSC directives. After scanning the parsed AST it rejects files that declare both 'use client' and 'use server': a module cannot simultaneously be a client boundary (exports proxied to the browser) and a server boundary (exports registered as server functions), so the hook throws before compiling.

Source

Thrown at packages/react-server-dom-unbundled/src/ReactFlightUnbundledNodeRegister.js:70

    for (let i = 0; i < body.length; i++) {
      const node = body[i];
      if (node.type !== 'ExpressionStatement' || !node.directive) {
        break;
      }
      if (node.directive === 'use client') {
        useClient = true;
      }
      if (node.directive === 'use server') {
        useServer = true;
      }
    }

    if (!useClient && !useServer) {
      return originalCompile.apply(this, arguments);
    }

    if (useClient && useServer) {
      throw new Error(
        'Cannot have both "use client" and "use server" directives in the same file.',
      );
    }

    if (useClient) {
      const moduleId: string = url.pathToFileURL(filename).href as any;
      this.exports = createClientModuleProxy(moduleId);
    }

    if (useServer) {
      originalCompile.apply(this, arguments);

      const moduleId: string = url.pathToFileURL(filename).href as any;

      const exports = this.exports;

      // This module is imported server to server, but opts in to exposing functions by
      // reference. If there are any functions in the export.

View on GitHub (pinned to eafeac097b)

Solutions

  1. Move server actions ("use server") into their own file and import them from the client component.
  2. Remove whichever directive does not match the file's intended boundary.
  3. Add a lint/CI check that rejects files containing both directive strings.

Example fix

// before: one file, both directives
"use client";
"use server";
export default function App() {}

// after
// app.js ("use client") imports { save } from './actions.js' ("use server")
"use client";
import { save } from './actions';
export default function App() {}
Defensive patterns

Strategy: validation

Validate before calling

// Lint rule (no-restricted-syntax style) or script check before register()
const src = fs.readFileSync(filename, 'utf8');
if (/^["']use client["']/m.test(src) && /^["']use server["']/m.test(src)) {
  throw new Error(`${filename}: split "use client" and "use server" into separate files`);
}

Prevention

When it happens

Trigger: A module compiled through `module.register(...)` / the unbundled node-register hook whose leading directives contain both "use client" and "use server".

Common situations: Adding a server action to an existing client component file instead of a new module; tutorial code merged incorrectly so both directive lines survive; codemods that prepend a directive without removing the existing one.

Related errors


AI-assisted analysis of facebook/react@eafeac097b (2026-08-21). Data as JSON: /api/errors/6cb970dc7ff57188. Report an issue: GitHub.