{"record":{"id":"928d7829ba8ebec3","repo":"facebook/react","slug":"expected-the-transformed-source-to-be-a-string","errorCode":null,"errorMessage":"Expected the transformed source to be a string.","messagePattern":"Expected the transformed source to be a string\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-server-dom-esm/src/ReactFlightESMNodeLoader.js","lineNumber":530,"sourceCode":"  parentURL: string,\n  loader: LoadFunction,\n): Promise<void> {\n  for (let i = 0; i < body.length; i++) {\n    const node = body[i];\n    switch (node.type) {\n      case 'ExportAllDeclaration':\n        if (node.exported) {\n          addExportNames(names, node.exported);\n          continue;\n        } else {\n          const {url} = await resolveClientImport(node.source.value, parentURL);\n          const {source} = await loader(\n            url,\n            {format: 'module', conditions: [], importAssertions: {}},\n            loader,\n          );\n          if (typeof source !== 'string') {\n            throw new Error('Expected the transformed source to be a string.');\n          }\n          let childBody;\n          try {\n            childBody = acorn.parse(source, {\n              ecmaVersion: '2024',\n              sourceType: 'module',\n            }).body;\n          } catch (x) {\n            // eslint-disable-next-line react-internal/no-production-logging\n            console.error('Error parsing %s %s', url, x.message);\n            continue;\n          }\n          await parseExportNamesInto(childBody, names, url, loader);\n          continue;\n        }\n      case 'ExportDefaultDeclaration':\n        names.push('default');\n        continue;","sourceCodeStart":512,"sourceCodeEnd":548,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-server-dom-esm/src/ReactFlightESMNodeLoader.js#L512-L548","documentation":"While handling `export * from ...` declarations, the RSC ESM loader recursively loads the re-exported module through the loader chain and expects result.source to be a string before parsing it with acorn to enumerate export names. Node's load hooks may legitimately return ArrayBuffer sources under newer protocol versions, and chained loaders can return other shapes; anything non-string hits this throw.","triggerScenarios":"A client-reference module that uses `export * from './other'` where the chained loader (or Node's default load for certain URL schemes/versions) returns an ArrayBuffer or null source; loaders like tsx/esbuild-register in the chain returning non-string sources; Node version drift in the load-hook contract under this package's supported matrix.","commonSituations":"Monorepos whose server graphs include barrel files re-exporting client components; combining the RSC loader with TypeScript loaders on newer Node; data: URLs or exotic loaders feeding non-string sources into the chain.","solutions":["Replace `export * from './client-mod'` with explicit named re-exports so the loader never needs to load and parse the child module","Ensure every loader in the chain normalizes source to a string (convert ArrayBuffer with new TextDecoder().decode(source) before returning)","Match react-server-dom-esm to a Node version its loader supports; check the package release notes for loader fixes"],"exampleFix":"// before (barrel re-export in a client boundary)\nexport * from './buttons';\n\n// after (explicit names)\nexport {Button, LinkButton} from './buttons';","handlingStrategy":"validation","validationCode":"// for loader-chain authors: normalize before returning\nasync function load(url, context, nextLoad) {\n  const result = await nextLoad(url, context);\n  if (result.source != null && typeof result.source !== 'string') {\n    result.source = new TextDecoder().decode(result.source);\n  }\n  return result;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Prefer explicit named re-exports over `export *` in modules that cross the client/server boundary","Keep loaders in the chain returning string sources","Match react-server-dom-esm and Node versions per the package's supported matrix"],"tags":["node-loader","esm","re-exports","react-server-components"],"backgroundTag":"loader-source-type-mismatch","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}