facebook/react · error · Error
Invalid server action: ${ref}
Error message
Invalid server action: ${ref} What it means
On the Parcel client, resolveServerReference splits a serialized id '<moduleId>#<exportName>' and requires bundlerConfig[moduleId] — the Server Manifest entry describing which bundles to load. The manifest is the second argument passed to createFromFetch/createFromNodeStream/createFromReadableStream. An unknown id means the client cannot locate the module implementing the action, so the call is rejected before any request is made.
Source
Thrown at packages/react-server-dom-parcel/src/client/ReactFlightClientConfigBundlerParcel.js:62
export function resolveClientReference<T>(
bundlerConfig: null,
metadata: ClientReferenceMetadata,
): ClientReference<T> {
// Reference is already resolved during the build.
return metadata;
}
export function resolveServerReference<T>(
bundlerConfig: ServerManifest,
ref: ServerReferenceId,
): ClientReference<T> {
const idx = ref.lastIndexOf('#');
const id = ref.slice(0, idx);
const name = ref.slice(idx + 1);
const bundles = bundlerConfig[id];
if (!bundles) {
throw new Error('Invalid server action: ' + ref);
}
return [id, name, bundles];
}
export function preloadModule<T>(
metadata: ClientReference<T>,
): null | Thenable<any> {
if (metadata[IMPORT_MAP]) {
parcelRequire.extendImportMap(metadata[IMPORT_MAP]);
}
if (metadata[BUNDLES].length === 0) {
return null;
}
return Promise.all(metadata[BUNDLES].map(url => parcelRequire.load(url)));
}
View on GitHub (pinned to eafeac097b)
Solutions
- Rebuild so the server manifest includes the new action's module id, and pass that manifest as the second argument to createFrom*
- Verify the id before calling: const id = ref.slice(0, ref.lastIndexOf('#')); if (!manifest[id]) the manifest is stale
- Make the payload and the manifest come from the same build artifact so ids never drift
Example fix
// before — manifest predates the action
const data = createFromFetch(fetch('/endpoint'), staleServerManifest);
await data.saveNote(); // Invalid server action: notes/saveNote#saveNote
// after — payload and manifest ship from the same build
const build = await import(`./build/manifest-${BUILD_ID}.js`);
const data = createFromFetch(fetch('/endpoint'), build.serverManifest);
await data.saveNote(); Defensive patterns
Strategy: validation
Validate before calling
export function isKnownServerAction(manifest, ref) {
const idx = ref.lastIndexOf('#');
return idx > 0 && Object.prototype.hasOwnProperty.call(manifest, ref.slice(0, idx));
}
// before invoking: if (!isKnownServerAction(serverManifest, id)) { refresh the manifest or surface an error } Type guard
export function parseServerReference(ref) {
const idx = ref.lastIndexOf('#');
return idx > 0 ? {id: ref.slice(0, idx), name: ref.slice(idx + 1)} : null;
} Try / catch
try {
await action(...args);
} catch (e) {
if (/Invalid server action/.test(e.message)) {
// manifest drift — reload the manifest for the current build and retry once
}
throw e;
} Prevention
- Ship the server manifest and the payload from the same build artifact
- Rebuild both client and server outputs after adding server actions
- Guard call sites with isKnownServerAction so drift fails with a clear message
When it happens
Trigger: Invoking a server function whose module id is absent from the manifest passed to createFrom*; a ref without a '#' so the parsed id is garbage; a manifest generated by an older build than the payload that references the action.
Common situations: Adding a new server action but shipping a stale client manifest; build pipelines emitting client and server artifacts from different revisions; passing the client-reference manifest where the server manifest belongs.
Related errors
- No server callback has been registered. Call setServerCallba
- Server actions must be functions
- Server actions must be functions
- Attempted to load a Server Reference outside the hosted root
- Server Functions cannot be called during initial render. Thi
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/48b5c106c7afd584.
Report an issue: GitHub.