React throws this error when a `<Suspense>` boundary never catches a Promise or an async child, so the runtime refuses to render the boundary or its fallback.
A `<Suspense>` boundary only makes sense when one of its descendants can suspend, which happens when a component either throws a `Promise` (such as an `async` server component that `await`s data or a `React.lazy` wrapper) or is streaming data. When the tree stays fully synchronous, React cannot show a fallback and therefore throws this intent-checking error to signal that the boundary is unnecessary or misconfigured. This safeguard was introduced as part of the concurrent/Server Component workflow so that React can reason about when to pause and resume rendering.
The mistake is almost always right next to the <code><Suspense></code> declaration. Look at the file listed in the stack trace and focus on the direct child of the boundary. If the child is a plain component like the one below, nothing inside the boundary suspends and React refuses to let it exist:
<pre><code class="language-tsx">// layout.tsx
import { Suspense } from 'react';
export default function Layout() {
return (
<Suspense fallback={<Loading />}>
<Hero /> // regular, synchronous server component
</Suspense>
);
}
</code></pre>
React throws the error before it tries to render Loading because it sees a Suspense boundary with only synchronous content.
Convert the component inside <code><Suspense></code> into an <code>async</code> server component that actually suspends by awaiting data or resources. For example:
<pre><code class="language-tsx">// components/Hero.tsx (server)
const Hero = async () => {
const res = await fetch('https://api.example.com/hero', { cache: 'no-store' });
const hero = await res.json();
return <section>{hero.title}</section>;
};
// layout.tsx
<Suspense fallback={<Loading />}>
<Hero />
</Suspense>
</code></pre>
await fetch causes React to suspend, satisfies the boundary, and React now streams the fallback until the promise resolves.
If the boundary wraps a client component, make that component asynchronous with React.lazy so the tree can suspend while the chunk loads:
<pre><code class="language-tsx">const Chart = React.lazy(() => import('./Chart'));
function Dashboard() {
return (
<Suspense fallback={<LoadingChart />}>
<Chart />
</Suspense>
);
}
</code></pre>
The promise that React.lazy returns keeps the boundary honest, and React stops throwing the error.
If there is no asynchronous work left, the easiest fix is to remove <code><Suspense></code> entirely. Keeping an unused boundary only invites this error:
<pre><code class="language-tsx">// remove Suspense when everything is synchronous
export default function Layout() {
return <Hero />; // no boundary needed when Hero renders right away
}
</code></pre>
Only wrap the tree with <code><Suspense></code> when you know it suspends (via await, data fetching helpers, or React.lazy).
Every Suspense boundary must still describe a fallback UI even if it eventually renders instantly. It is safe to add a boundary above a chunk that may or may not suspend as long as at least one descendant actually throws a promise. This is why server architects often place <Suspense> around the portion of the tree that calls await use or await fetch. React validates that requirement early to avoid streaming meaningless fallbacks or confusing builds when using server components.
React Hook useCallback has a missing dependency: 'variable'. Either include it or remove the dependency array react-hooks/exhaustive-deps
React Hook useCallback has a missing dependency
Cannot use private fields in class components without TS support
Cannot use private fields in class components without TS support
Cannot destructure property 'xxx' of 'undefined'
Cannot destructure property of undefined when accessing props
useNavigate() may be used only in the context of a <Router> component.
useNavigate() may be used only in the context of a Router component
Cannot find module or its corresponding type declarations
How to fix "Cannot find module or type declarations" in Vite