facebook/react · error · Error

515

515

Error message

Cannot assign to a temporary client reference from a server module.

What it means

The setter half of the temporary-reference proxy: server code attempted to assign a property onto a value that is an opaque client-side handle. Temporary references are pass-through values with no server-side storage, so mutation is meaningless and rejected immediately. This is usually accidental — a helper that caches results on objects, or middleware that decorates its inputs.

Source

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

        // which will be serialized and executed on the client.
        return receiver;
      case 'then':
        // Allow returning a temporary reference from an async function
        // Unlike regular Client References, a Promise would never have been serialized as
        // an opaque Temporary Reference, but instead would have been serialized as a
        // Promise on the server and so doesn't hit this path. So we can assume this wasn't
        // a Promise on the client.
        return undefined;
    }
    throw new Error(
      // eslint-disable-next-line react-internal/safe-string-coercion
      `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,
    {

View on GitHub (pinned to eafeac097b)

Solutions

  1. Remove mutation of pass-through values; derive new local values instead of decorating them.
  2. Carry any metadata in a separate plain object alongside the reference.
  3. Identity-check values against the temporaryReferences store and treat matches as frozen.

Example fix

// before
function handle(fileRef) { fileRef.seen = true; return passOn(fileRef); }

// after
function handle(fileRef) { const meta = {seen: true}; return passOn(fileRef, meta); }
Defensive patterns

Strategy: validation

Validate before calling

export function safeAnnotate<T extends object>(
  v: T, key: string, value: unknown, tempRefs: WeakMap<object, string>,
): T {
  if (tempRefs.has(v)) return v; // opaque pass-through — do not mutate
  (v as any)[key] = value;
  return v;
}

Type guard

export function isTemporaryReference(v: unknown, store: WeakMap<object, string>): boolean {
  return typeof v === 'object' && v !== null && store.has(v);
}

Try / catch

try {
  v.seen = true;
} catch (e) {
  if (!String((e as Error)?.message).includes('temporary client reference')) throw e;
  // else: leave the pass-through value untouched
}

Prevention

When it happens

Trigger: fileRef.processed = true; args[0].meta = {...}; any assignment (including ||= / default-filling) to a value that came out of decodeReply's temporaryReferences; third-party libraries that mutate their arguments.

Common situations: Memoization helpers stamping objects; middleware annotating request values; validation libraries that normalize inputs in place.

Related errors


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