facebook/react · error · Error

516

516

Error message

Attempted to call a temporary Client Reference from the server but it is on the client. It's not possible to invoke a client function from the server, it can only be rendered as a Component or passed to props of a Client Component.

What it means

The temporary-reference wrapper is itself a function so it can sit in component/function positions, but calling it on the server is rejected: the callable value lives on the client and cannot be invoked across the boundary. React throws with the explicit direction — render it as a Component or forward it to Client Component props, never call it from server code.

Source

Thrown at packages/react-server/src/ReactFlightServerTemporaryReferences.js:100

      `Cannot access ${String(name)} on the server. ` +
        'You cannot dot into a temporary client reference from a server component. ' +
        'You can only pass the value through to the client.',
    );
  },
  set: function () {
    throw new Error(
      'Cannot assign to a temporary client reference from a server module.',
    );
  },
};

export function createTemporaryReference<T>(
  temporaryReferences: TemporaryReferenceSet,
  id: string,
): TemporaryReference<T> {
  const reference: TemporaryReference<any> = Object.defineProperties(
    function () {
      throw new Error(
        `Attempted to call a temporary Client Reference from the server but it is on the client. ` +
          `It's not possible to invoke a client function from the server, it can ` +
          `only be rendered as a Component or passed to props of a Client Component.`,
      );
    } as any,
    {
      $$typeof: {value: TEMPORARY_REFERENCE_TAG},
    },
  );
  const wrapper = new Proxy(reference, proxyHandlers);
  registerTemporaryReference(temporaryReferences, wrapper, id);
  return wrapper;
}

export function registerTemporaryReference(
  temporaryReferences: TemporaryReferenceSet,
  object: TemporaryReference<any>,
  id: string,

View on GitHub (pinned to eafeac097b)

Solutions

  1. Return data from the action and let the client continue the flow with the result.
  2. Pass the callback through to a Client Component that invokes it in the browser.
  3. Replace the callback contract with a returned value or a follow-up server action the client calls.

Example fix

// before — server action
'use server';
export async function run(cb) { const r = compute(); cb(r); }

// after — return the result; the client continues
'use server';
export async function run() { return compute(); }
// client
const r = await run(); onDone(r);
Defensive patterns

Strategy: type-guard

Validate before calling

export function assertNotClientCallable(v: unknown, tempRefs: WeakMap<object, string>) {
  if (typeof v === 'function' && tempRefs.has(v)) {
    throw new Error('refusing to invoke a client-held temporary reference from the server');
  }
}

Type guard

export function isTemporaryReference(v: unknown, store: WeakMap<object, string>): v is (...a: any[]) => any {
  return store.has(v as object);
}

Try / catch

try {
  cb();
} catch (e) {
  if (String((e as Error)?.message).includes('temporary Client Reference')) {
    return respondWith('callback cannot run on the server; returning action result instead');
  }
  throw e;
}

Prevention

When it happens

Trigger: A Server Action receives a client callback as an argument and invokes it (const cb = args[0]; cb()); passing a temp ref into a higher-order server utility that calls function-typed arguments generically.

Common situations: Porting callback-style APIs (done(err), onSuccess(...)) into server actions; libraries that call any function-typed parameter; continuing an async flow from the server by 'notifying' the client.

Related errors


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