{"record":{"id":"20054dffdbd082de","repo":"facebook/react","slug":"failed-to-parse-source-file-originalsourceurl","errorCode":null,"errorMessage":"Failed to parse source file: ${originalSourceURL}\n\nOriginal error: ${error}","messagePattern":"Failed to parse source file: (.+?)\n\nOriginal error: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/react-devtools-shared/src/hooks/parseHookNames/parseSourceAndMetadata.js","lineNumber":380,"sourceCode":"                sourceType: 'unambiguous',\n                plugins: ['jsx', plugin],\n              }),\n          );\n          hookParsedMetadata.originalSourceAST = originalSourceAST;\n\n          // $FlowFixMe[constant-condition]\n          if (__DEBUG__) {\n            console.log(\n              `parseSourceAST() Caching source metadata for \"${originalSourceURL}\"`,\n            );\n          }\n\n          originalURLToMetadataCache.set(originalSourceURL, {\n            originalSourceAST,\n            originalSourceCode,\n          });\n        } catch (error) {\n          throw new Error(\n            `Failed to parse source file: ${originalSourceURL}\\n\\n` +\n              `Original error: ${error}`,\n          );\n        }\n      }\n    },\n  );\n}\n\nfunction parseSourceMaps(\n  locationKeyToHookSourceAndMetadata: LocationKeyToHookSourceAndMetadata,\n  locationKeyToHookParsedMetadata: LocationKeyToHookParsedMetadata,\n) {\n  locationKeyToHookSourceAndMetadata.forEach(\n    (hookSourceAndMetadata, locationKey) => {\n      const hookParsedMetadata =\n        locationKeyToHookParsedMetadata.get(locationKey);\n      if (hookParsedMetadata == null) {","sourceCodeStart":362,"sourceCodeEnd":398,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react-devtools-shared/src/hooks/parseHookNames/parseSourceAndMetadata.js#L362-L398","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Add '// @flow' to Flow sources so they are parsed with the flow plugin instead of typescript.","Upgrade React DevTools — its bundled @babel/parser gains newer syntax support over time.","Verify the mapped sources are the real pre-compile originals (correct sourcesContent, right file served).","Treat as non-fatal: catch this error and fall back to unnamed hooks (indices only)."],"exampleFix":"// before — Flow file without a pragma, parsed as TypeScript → parse error\nexport default function useFoo(): boolean { return true; }\n\n// after\n// @flow\nexport default function useFoo(): boolean { return true; }","handlingStrategy":"try-catch","validationCode":"function isParseableSource(url) {\n  return /\\.(jsx?|tsx?|mjs|cjs)$/.test(url);\n}\nif (isParseableSource(originalSourceURL)) {\n  parseSourceAndMetadata(locationKeyToSourceAndMetadata, locationKeyToHookParsedMetadata);\n}","typeGuard":"function isParseableSource(url) {\n  return /\\.(jsx?|tsx?|mjs|cjs)$/.test(url);\n}","tryCatchPattern":"try {\n  parseHookNames(locationKeyToHookSourceAndMetadata, locationKeyToHookParsedMetadata);\n} catch (error) {\n  if (/^Failed to parse source file/.test(error.message)) {\n    // Hook names unavailable for this source; degrade to hook indices\n    return null;\n  }\n  throw error;\n}","preventionTips":["Keep '// @flow' pragmas on every Flow file mapped by your source maps.","Ensure sourcesContent/original sources are the actual pre-compile files.","Upgrade React DevTools to pick up a newer @babel/parser.","Wrap hook-name parsing so one bad file degrades gracefully instead of failing the feature."],"tags":["devtools","babel","parser","source-map","hooks","flow","typescript"],"backgroundTag":"babel-parse-error","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}