LearnTroubleshooting

Troubleshooting

This guide contains warnings and errors that can occur when using React Flow. We are also adding common questions and pitfalls that we collect from our Discord Server, Github Issues and Github Discussions.

Warning: Seems like you have not used zustand provider as an ancestor

This usually happens when:

A: You have two different version of @reactflow/core installed.
B: You are trying to access the internal React Flow state outside of the React Flow context.

Solution for A

Update reactflow and @reactflow/node-resizer (in case you are using it), remove node_modules and package-lock.json and reinstall the dependencies.

Solution for B

A possible solution is to wrap your component with a <ReactFlowProvider /> or move the code that is accessing the state inside a child of your React Flow instance.

🚫
This will cause an error:
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
function FlowWithoutProvider(props) {
  // cannot access the state here
  const reactFlowInstance = useReactFlow();
 
  return <ReactFlow {...props} />;
}
 
export default FlowWithoutProvider;
🚫
This will cause an error, too:
import { ReactFlow, ReactFlowProvider } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
function Flow(props) {
  // still cannot access the state here
  // only child components of this component can access the state
  const reactFlowInstance = useReactFlow();
 
  return (
    <ReactFlowProvider>
      <ReactFlow {...props} />
    </ReactFlowProvider>
  );
}
 
export default FlowWithProvider;
This works:

As soon as you want to access the internal state of React Flow (for example by using the useReactFlow hook), you need to wrap your component with a <ReactFlowProvider />. Here the wrapping is done outside of the component:

import { ReactFlow, ReactFlowProvider } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
function Flow(props) {
  // you can access the internal state here
  const reactFlowInstance = useReactFlow();
 
  return <ReactFlow {...props} />;
}
 
// wrapping with ReactFlowProvider is done outside of the component
function FlowWithProvider(props) {
  return (
    <ReactFlowProvider>
      <Flow {...props} />
    </ReactFlowProvider>
  );
}
 
export default FlowWithProvider;

It looks like you have created a new nodeTypes or edgeTypes object. If this wasn’t

on purpose please define the nodeTypes/edgeTypes outside of the component or memoize them.

This warning appears when the nodeTypes or edgeTypes properties change after the initial render. The nodeTypes or edgeTypes should only be changed dynamically in very rare cases. Usually they are defined once with all the types that you are using in your application. It can happen easily that you are defining the nodeTypes or edgeTypes object inside of your component render function, which will cause React Flow to re-render every time your component re-renders.

🚫
Causes a warning:
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
import MyCustomNode from './MyCustomNode';
 
function Flow(props) {
  // new object being created on every render
  // causing unneccessary re-renders
  const nodeTypes = {
    myCustomNode: MyCustomNode,
  };
 
  return <ReactFlow nodeTypes={nodeTypes} />;
}
 
export default Flow;
Recommended implementation:
import { ReactFlow } from '@xyflow/react';
import MyCustomNode from './MyCustomNode';
 
// defined outside of the component
const nodeTypes = {
  myCustomNode: MyCustomNode,
};
 
function Flow(props) {
  return <ReactFlow nodeTypes={nodeTypes} />;
}
 
export default Flow;
Alternative implementation:

You can use this if you want to change your nodeTypes dynamically without causing unneccessary re-renders.

import { useMemo } from 'react';
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
import MyCustomNode from './MyCustomNode';
 
function Flow(props) {
  const nodeTypes = useMemo(
    () => ({
      myCustomNode: MyCustomNode,
    }),
    [],
  );
 
  return <ReactFlow nodeTypes={nodeTypes} />;
}
 
export default Flow;

Node type not found. Using fallback type “default”.

This usually happens when you are specifying a custom node type for one of your nodes but not passing the correct nodeTypes property to React Flow. The string for the type option of your custom node needs to be exactly the same as the key of the nodeTypes object.

🚫
Doesn’t work:
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
import MyCustomNode from './MyCustomNode';
 
const nodes = [
  {
    id: 'mycustomnode',
    type: 'custom',
    // ...
  },
];
 
function Flow(props) {
  // nodeTypes property is missing, so React Flow cannot find the custom node component to render
  return <ReactFlow nodes={nodes} />;
}
🚫
Doesn’t work either:
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
import MyCustomNode from './MyCustomNode';
 
const nodes = [
  {
    id: 'mycustomnode',
    type: 'custom',
    // ...
  },
];
 
const nodeTypes = {
  Custom: MyCustomNode,
};
 
function Flow(props) {
  // node.type and key in nodeTypes object are not exactly the same (capitalized)
  return <ReactFlow nodes={nodes} nodeTypes={nodeTypes} />;
}
This does work:
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
import MyCustomNode from './MyCustomNode';
 
const nodes = [
  {
    id: 'mycustomnode',
    type: 'custom',
    // ...
  },
];
 
const nodeTypes = {
  custom: MyCustomNode,
};
 
function Flow(props) {
  return <ReactFlow nodes={nodes} nodeTypes={nodeTypes} />;
}

The React Flow parent container needs a width and a height to render the graph.

Under the hood, React Flow measures the parent DOM element to adjust the renderer. If you try to render React Flow in a regular div without a height, we cannot display the graph. If you encounter this warning, you need to make sure that your wrapper component has some CSS attached to it so that it gets a fixed height or inherits the height of its parent.

🚫
This will cause the warning:
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
function Flow(props) {
  return (
    <div>
      <ReactFlow {...props} />
    </div>
  );
}
Working example:
import { ReactFlow } from '@xyflow/react';
 
function Flow(props) {
  return (
    <div style={{ height: 800 }}>
      <ReactFlow {...props} />
    </div>
  );
}

Only child nodes can use a parent extent.

This warning appears when you are trying to add the extent option to a node that does not have a parent node. Depending on what you are trying to do, you can remove the extent option or specify a parentNode.

🚫
Does show a warning:
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
const nodes = [
  {
    id: 'mycustomnode',
    extent: 'parent',
    // ...
  },
];
 
function Flow(props) {
  return <ReactFlow nodes={nodes} />;
}
Warning resolved:
const nodes = [
  {
    id: 'mycustomnode',
    parentNode: 'someothernode',
    extent: 'parent',
    // ...
  },
];
 
function Flow(props) {
  return <ReactFlow nodes={nodes} />;
}

Can’t create edge. An edge needs a source and a target.

This happens when you do not pass a source and a target option to the edge object. Without the source and target, the edge cannot be rendered.

🚫
Will show a warning:
import { ReactFlow } from '@xyflow/react';
import '@xyflow/react/dist/style.css';
 
const nodes = [
  /* ... */
];
 
const edges = [
  {
    nosource: '1',
    notarget: '2',
  },
];
 
function Flow(props) {
  return <ReactFlow nodes={nodes} edges={edges} />;
}
This works:
import { ReactFlow } from '@xyflow/react';
 
const nodes = [
  /* ... */
];
 
const edges = [
  {
    source: '1',
    target: '2',
  },
];
 
function Flow(props) {
  return <ReactFlow nodes={nodes} edges={edges} />;
}

The old edge with id=“some-id” does not exist.

This can happen when you are trying to reconnect an edge but the edge you want to update is already removed from the state. This is a very rare case. Please see the Reconnect Edge example for implementation details.

Couldn’t create edge for source/target handle id: “some-id”; edge id: “some-id”.

This can happen if you are working with multiple handles and a handle is not found by its id property or if you haven’t updated the node internals after adding or removing handles programmatically. Please see the Custom Node Example for an example of working with multiple handles.

Marker type doesn’t exist.

This warning occurs when you are trying to specify a marker type that is not built into React Flow. The existing marker types are documented here.

Handle: No node id found.

This warning occurs when you try to use a <Handle /> component outside of a custom node component.

I get an error when building my app with webpack 4.

If you’re using webpack 4, you’ll likely run into an error like this:

ERROR in /node_modules/@reactflow/core/dist/esm/index.js 16:19
Module parse failed: Unexpected token (16:19)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

React Flow is a modern JavaScript code base and makes use of lots of newer JavaScript features. By default, webpack 4 does not transpile your code and it doesn’t know how to handle React Flow.

You need to add a number of babel plugins to your webpack config to make it work:

$ npm i --save-dev babel-loader@8.2.5 @babel/preset-env @babel/preset-react @babel/plugin-proposal-optional-chaining @babel/plugin-proposal-nullish-coalescing-operator

and configure the loader like this:

{
  test: /node_modules[\/\\]@?reactflow[\/\\].*.js$/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: ['@babel/preset-env', "@babel/preset-react"],
      plugins: [
        "@babel/plugin-proposal-optional-chaining",
        "@babel/plugin-proposal-nullish-coalescing-operator",
      ]
    }
  }
}

If you’re using webpack 5, you don’t need to do anything! React Flow will work out of the box.

Mouse events aren’t working consistently when my nodes contain a <canvas /> element.

If you’re using a <canvas /> element inside your custom node, you might run into problems with seemingly-incorrect coordinates in mouse events from the cavnas.

React Flow uses CSS transforms to scale nodes as you zoom in and out. From the DOM’s perspective, however, the element is still the same size. This can cause problems if you have event listeners that want to calcuate the mouse position relative to the canvas element.

To remedy this in event handlers you control, you can scale your computed relative position by 1 / zoom where zoom is the current zoom level of the flow. To get the current zoom level, you can use the getZoom method from the useReactFlow hook.