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
- Remove mutation of pass-through values; derive new local values instead of decorating them.
- Carry any metadata in a separate plain object alongside the reference.
- 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
- Treat action-reply values as immutable pass-throughs.
- Keep metadata in separate structures keyed by the reference id.
- Identity-check unknown inputs against the temporaryReferences store before decorating them.
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
- 514
- Cannot assign to a client module from a server module.
- Attempted to call ${String(name)}() from the server but ${St
- Cannot assign to a client module from a server module.
- 526
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/f01f6ca1e8e07dd3.
Report an issue: GitHub.