facebook/react · error · Error

Failed to parse source file: ${originalSourceURL} Original

Error message

Failed to parse source file: ${originalSourceURL}

Original error: ${error}

What it means

While resolving hook names, DevTools fetches the original source named by the source map and parses it with @babel/parser using the jsx plugin plus 'typescript' — unless the source contains '@flow', in which case the flow plugin is used. Any parse failure is re-thrown wrapped with the file URL and the original parser error, so the message tells you both which file and why.

Source

Thrown at packages/react-devtools-shared/src/hooks/parseHookNames/parseSourceAndMetadata.js:380

                sourceType: 'unambiguous',
                plugins: ['jsx', plugin],
              }),
          );
          hookParsedMetadata.originalSourceAST = originalSourceAST;

          // $FlowFixMe[constant-condition]
          if (__DEBUG__) {
            console.log(
              `parseSourceAST() Caching source metadata for "${originalSourceURL}"`,
            );
          }

          originalURLToMetadataCache.set(originalSourceURL, {
            originalSourceAST,
            originalSourceCode,
          });
        } catch (error) {
          throw new Error(
            `Failed to parse source file: ${originalSourceURL}\n\n` +
              `Original error: ${error}`,
          );
        }
      }
    },
  );
}

function parseSourceMaps(
  locationKeyToHookSourceAndMetadata: LocationKeyToHookSourceAndMetadata,
  locationKeyToHookParsedMetadata: LocationKeyToHookParsedMetadata,
) {
  locationKeyToHookSourceAndMetadata.forEach(
    (hookSourceAndMetadata, locationKey) => {
      const hookParsedMetadata =
        locationKeyToHookParsedMetadata.get(locationKey);
      if (hookParsedMetadata == null) {

View on GitHub (pinned to eafeac097b)

Solutions

  1. Add '// @flow' to Flow sources so they are parsed with the flow plugin instead of typescript.
  2. Upgrade React DevTools — its bundled @babel/parser gains newer syntax support over time.
  3. Verify the mapped sources are the real pre-compile originals (correct sourcesContent, right file served).
  4. Treat as non-fatal: catch this error and fall back to unnamed hooks (indices only).

Example fix

// before — Flow file without a pragma, parsed as TypeScript → parse error
export default function useFoo(): boolean { return true; }

// after
// @flow
export default function useFoo(): boolean { return true; }
Defensive patterns

Strategy: try-catch

Validate before calling

function isParseableSource(url) {
  return /\.(jsx?|tsx?|mjs|cjs)$/.test(url);
}
if (isParseableSource(originalSourceURL)) {
  parseSourceAndMetadata(locationKeyToSourceAndMetadata, locationKeyToHookParsedMetadata);
}

Type guard

function isParseableSource(url) {
  return /\.(jsx?|tsx?|mjs|cjs)$/.test(url);
}

Try / catch

try {
  parseHookNames(locationKeyToHookSourceAndMetadata, locationKeyToHookParsedMetadata);
} catch (error) {
  if (/^Failed to parse source file/.test(error.message)) {
    // Hook names unavailable for this source; degrade to hook indices
    return null;
  }
  throw error;
}

Prevention

When it happens

Trigger: parseSourceAST() runs on the original source for a hook call site and @babel/parser rejects it — e.g. Flow syntax parsed as TypeScript because the '// @flow' pragma is missing, syntax newer than the vendored parser (decorators, newer TS), or a mapped 'source' that is not plain JS/TS (HTML with inline scripts, template files).

Common situations: Flow projects where some files lack the pragma; TypeScript using syntax newer than the parser bundled in that DevTools release; sourcesContent pointing at transpiled or non-JS output; hook-name inspection enabled against exotic toolchains.

Understand the failure class

Related errors


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