facebook/flow · error

No visitor keys found for node type

Error message

No visitor keys found for node type "${node.type}".

What it means

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.

Solutions

  1. Pass the matching visitorKeys option: getVisitorKeys(node, myVisitorKeys) / SimpleTransform with visitorKeys covering your AST's node types.
  2. Use parser/traverse/transform helpers from the same package that produced the AST.
  3. Align versions: upgrade flow-parser so its FlowVisitorKeys include the node type named in the message.
  4. For custom node types, extend the visitor keys map with entries for them before traversal.

Example fix

// before
const ast = tsParse(code); // TSESTree nodes
SimpleTransform.transformProgram(ast, {transform}); // no visitorKeys -> throws on TS* nodes

// after
import {visitorKeys as tsVisitorKeys} from './tsVisitorKeys.js';
SimpleTransform.transformProgram(tsAst, {transform, visitorKeys: {...FlowVisitorKeys, ...tsVisitorKeys}});
Defensive patterns

Strategy: type-guard

Validate before calling

// Verify coverage before traversing
import {visitorKeys as FlowVisitorKeys} from 'flow-parser';
function astTypesCovered(ast, extra = {}) {
  const keys = {...FlowVisitorKeys, ...extra};
  const missing = new Set();
  (function walk(n) {
    if (n == null || typeof n !== 'object') return;
    if (typeof n.type === 'string' && keys[n.type] == null) missing.add(n.type);
    for (const v of Object.values(n)) { if (Array.isArray(v)) v.forEach(walk); else walk(v); }
  })(ast);
  return {ok: missing.size === 0, missing: [...missing]};
}

Type guard

import {visitorKeys as FlowVisitorKeys} from 'flow-parser';
function hasVisitorKeys(node, visitorKeys) {
  return (visitorKeys ?? FlowVisitorKeys)[node.type] != null;
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of facebook/flow@f88ac94bcf (2026-08-20). Data as JSON: /api/errors/bf6df1fe354931bd. Report an issue: GitHub.

Appendix: source

Thrown at packages/flow-parser/oxidized-src/traverse/getVisitorKeys.js:31

import type {ESNode} from 'flow-estree';
import type {VisitorKeys as VisitorKeysType} from '../generated/ESTreeVisitorKeys';

import FlowVisitorKeys from '../generated/ESTreeVisitorKeys';

export function isNode(thing: unknown) /*: implies thing is {readonly [string]: unknown} */ {
  return (
    typeof thing === 'object' && thing != null && typeof thing.type === 'string'
  );
}

export type {VisitorKeysType};
export function getVisitorKeys<T extends ESNode>(
  node: T,
  visitorKeys?: ?VisitorKeysType,
) /*: ReadonlyArray<keyof T> */ {
  const keys = (visitorKeys ?? FlowVisitorKeys)[node.type];
  if (keys == null) {
    throw new Error(`No visitor keys found for node type "${node.type}".`);
  }

  // $FlowExpectedError[prop-missing]
  return keys;
}

View on GitHub (pinned to f88ac94bcf)