facebook/react · error · Error
Expected source to have been transformed to a string.
Error message
Expected source to have been transformed to a string.
What it means
In the loader's transformSource hook, the source returned by defaultTransformSource for format 'module' must be a plain string, because React parses it (directive scan, client-import rewriting) with its own tooling. Node permits hook results of string, ArrayBuffer, or Uint8Array; any binary representation that reaches this point fails the invariant.
Source
Thrown at packages/react-server-dom-esm/src/ReactFlightESMNodeLoader.js:772
}
return transformServerModule(source, program, url, sourceMap, loader);
}
export async function transformSource(
source: Source,
context: TransformSourceContext,
defaultTransformSource: TransformSourceFunction,
): Promise<{source: Source}> {
const transformed = await defaultTransformSource(
source,
context,
defaultTransformSource,
);
if (context.format === 'module') {
const transformedSource = transformed.source;
if (typeof transformedSource !== 'string') {
throw new Error('Expected source to have been transformed to a string.');
}
const newSrc = await transformModuleIfNeeded(
transformedSource,
context.url,
(url: string, ctx: LoadContext, defaultLoad: LoadFunction) => {
return loadClientImport(url, defaultTransformSource);
},
);
return {source: newSrc};
}
return transformed;
}
export async function load(
url: string,
context: LoadContext,
defaultLoad: LoadFunction,
): Promise<{format: string, shortCircuit?: boolean, source: Source}> {View on GitHub (pinned to eafeac097b)
Solutions
- Fix the earlier loader so JS module sources are returned as utf-8 strings
- Insert a small adapter hook before React's that decodes binary sources with new TextDecoder().decode(source) for format 'module'
- Drop --experimental-network-imports or other schemes that yield binary module sources
Example fix
// before — chained loader hands React a Buffer for module format
export async function transformSource(source, context, dflt) {
const r = await dflt(source, context, dflt);
return r; // source is a Uint8Array here
}
// after — always hand React a string for module format
export async function transformSource(source, context, dflt) {
const r = await dflt(source, context, dflt);
if (context.format === 'module' && typeof r.source !== 'string') {
return {...r, source: new TextDecoder().decode(r.source)};
}
return r;
} Defensive patterns
Strategy: validation
Validate before calling
// in any chained hook you control, enforce the invariant before React's hook runs
export async function transformSource(source, context, dflt) {
const r = await dflt(source, context, dflt);
if (context.format === 'module' && typeof r.source !== 'string') {
return {...r, source: new TextDecoder().decode(r.source)};
}
return r;
} Type guard
export function isStringModuleSource(result) {
return result.format !== 'module' || typeof result.source === 'string';
} Try / catch
try {
await import(url);
} catch (e) {
if (/transformed to a string/.test(e.message)) {
console.error('A chained loader returned binary source for', url);
}
throw e;
} Prevention
- Keep module-format sources as utf-8 strings across your whole loader chain
- Decode binary sources at the boundary where they enter the chain
- Avoid experimental network imports in RSC builds
When it happens
Trigger: A loader earlier in the chain returns {format: 'module', source: Buffer|Uint8Array|ArrayBuffer}, or the module comes from a scheme whose source Node produces as binary (for example network imports under --experimental-network-imports), and it flows into transformSource.
Common situations: Chaining asset or transpilation loaders (tsx, esbuild, CSS loaders) that return Buffers; Node major upgrades changing default source types; data: or http: module imports.
Related errors
- Expected source to have been loaded into a string.
- Expected getSource to have been called before transformSourc
- react-dom/client is not supported in React Server Components
- react-dom/profiling is not supported in React Server Compone
- react-dom/server is not supported in React Server Components
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/e9da8a7c15069448.
Report an issue: GitHub.