{"record":{"id":"bf6df1fe354931bd","repo":"facebook/flow","slug":"no-visitor-keys-found-for-node-type-node-type","errorCode":null,"errorMessage":"No visitor keys found for node type \"${node.type}\".","messagePattern":"No visitor keys found for node type \"(.+?)\"\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/flow-parser/oxidized-src/traverse/getVisitorKeys.js","lineNumber":31,"sourceCode":"import type {ESNode} from 'flow-estree';\nimport type {VisitorKeys as VisitorKeysType} from '../generated/ESTreeVisitorKeys';\n\nimport FlowVisitorKeys from '../generated/ESTreeVisitorKeys';\n\nexport function isNode(thing: unknown) /*: implies thing is {readonly [string]: unknown} */ {\n  return (\n    typeof thing === 'object' && thing != null && typeof thing.type === 'string'\n  );\n}\n\nexport type {VisitorKeysType};\nexport function getVisitorKeys<T extends ESNode>(\n  node: T,\n  visitorKeys?: ?VisitorKeysType,\n) /*: ReadonlyArray<keyof T> */ {\n  const keys = (visitorKeys ?? FlowVisitorKeys)[node.type];\n  if (keys == null) {\n    throw new Error(`No visitor keys found for node type \"${node.type}\".`);\n  }\n\n  // $FlowExpectedError[prop-missing]\n  return keys;\n}\n","sourceCodeStart":13,"sourceCodeEnd":37,"githubUrl":"https://github.com/facebook/flow/blob/f88ac94bcf6992f5d5a158854d94613ebb92c6e6/packages/flow-parser/oxidized-src/traverse/getVisitorKeys.js#L13-L37","documentation":"getVisitorKeys returns the traversal keys for a node type from the supplied visitorKeys map or the default FlowVisitorKeys. A node whose type string has no entry means the traverser/transformer does not know that AST dialect's shape, so it throws rather than silently skipping children.","triggerScenarios":"Traversing or SimpleTransform-ing an AST containing node types absent from Flow's visitor keys: TypeScript AST nodes from typescript-estree, Babel-flavored nodes, custom/invented node types, or future Flow node types when using an older parser package.","commonSituations":"Mixing parsers in one pipeline (parse with TS parser, transform with flow-parser helpers); version skew where a newer parser emits a node type the installed flow-parser's visitor keys lack; hand-crafted ASTs for testing.","solutions":["Pass the matching visitorKeys option: getVisitorKeys(node, myVisitorKeys) / SimpleTransform with visitorKeys covering your AST's node types.","Use parser/traverse/transform helpers from the same package that produced the AST.","Align versions: upgrade flow-parser so its FlowVisitorKeys include the node type named in the message.","For custom node types, extend the visitor keys map with entries for them before traversal."],"exampleFix":"// before\nconst ast = tsParse(code); // TSESTree nodes\nSimpleTransform.transformProgram(ast, {transform}); // no visitorKeys -> throws on TS* nodes\n\n// after\nimport {visitorKeys as tsVisitorKeys} from './tsVisitorKeys.js';\nSimpleTransform.transformProgram(tsAst, {transform, visitorKeys: {...FlowVisitorKeys, ...tsVisitorKeys}});","handlingStrategy":"type-guard","validationCode":"// Verify coverage before traversing\nimport {visitorKeys as FlowVisitorKeys} from 'flow-parser';\nfunction astTypesCovered(ast, extra = {}) {\n  const keys = {...FlowVisitorKeys, ...extra};\n  const missing = new Set();\n  (function walk(n) {\n    if (n == null || typeof n !== 'object') return;\n    if (typeof n.type === 'string' && keys[n.type] == null) missing.add(n.type);\n    for (const v of Object.values(n)) { if (Array.isArray(v)) v.forEach(walk); else walk(v); }\n  })(ast);\n  return {ok: missing.size === 0, missing: [...missing]};\n}","typeGuard":"import {visitorKeys as FlowVisitorKeys} from 'flow-parser';\nfunction hasVisitorKeys(node, visitorKeys) {\n  return (visitorKeys ?? FlowVisitorKeys)[node.type] != null;\n}","tryCatchPattern":null,"preventionTips":["Pass visitorKeys matching the AST dialect whenever transforming non-Flow ASTs.","Use parse/traverse/transform from the same package version as the AST producer.","On parser upgrades, watch release notes for new node types and re-check coverage."],"tags":["flow","parser","ast","traversal","visitor-keys","version-skew"],"backgroundTag":"unknown-node-type","analyzedSha":"f88ac94bcf6992f5d5a158854d94613ebb92c6e6","analyzedAt":"2026-08-20T10:41:37.992Z","contentChangedAt":"2026-08-20T10:41:37.992Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}