A reference of 33 common frontend and Node.js errors: for each one, the exact message text obtained by reproducing it on Node.js 24, React 19.3, Vite 8 and Next.js 16.4, the cause, the fix and how to prevent it. Search by the first line of the error: the type (TypeError, SyntaxError) and the text after the colon point to the section. Most React and TypeScript errors are caught by the linter and tsc before the code even runs.
After this you will be able to
- Find the cause and fix for 33 common JavaScript, TypeScript, React, Next.js, Node.js and npm errors from the message text
- Tell a data error (
undefined, HTML instead of JSON) from an environment error (ECONNREFUSED,EADDRINUSE, CORS) - Fix hydration errors and Server/Client Component boundary errors in the Next.js App Router
- Set up the linter and
tscso some errors are caught before running
Know beforehand
Verified with
Node.js 24 (24.21.0, образ node:24.21.0-alpine)npm 11.19TypeScript 7.0.2React 19.3Vite 8.3Next.js 16.4 (Turbopack)Chrome 154
Checked against docs: October 12, 2026
Contents
- JavaScript: TypeError and ReferenceError
- Async and network: await, promises, fetch, JSON, CORS
- Node.js and npm: modules, dependencies, ports
- TypeScript: TS2322, TS2339, TS2345, TS18048, TS7006, TS2307
- React: re-renders, keys and the Rules of Hooks
- Next.js: hydration, Server and Client Components
- How to find the answer yourself
JavaScript: TypeError and ReferenceError
Every message below is real output: we reproduced each error in temporary projects, the browser ones in Chrome 154. Long stacks are trimmed to the first line with your code; reading a full stack is covered in the article on debugging and stack traces. Chrome and Node.js messages match because they share the V8 engine; Firefox and Safari word them differently.
file:///app/01-undefined.mjs:2
console.log(user.address.city);
^
TypeError: Cannot read properties of undefined (reading 'city')
at file:///app/01-undefined.mjs:2:26- Cause — reading a property of an
undefinedvalue: hereuserhas noaddress. Most often the data hasn’t loaded yet, the API returned a different shape or a field name has a typo. The parentheses show the property being read, so look at whatever is to its left. - Fix — check the value before access: optional chaining
?.plus a default with??. - Prevention — describe the data shape with TypeScript types and validate API responses at the boundary, not deep inside components.
const user = { name: "Aigerim" };
console.log(user.address?.city ?? "city not set");city not set instead of throwing.file:///app/02-not-a-function.mjs:2
const doubled = data.map((x) => x * 2);
^
TypeError: data.map is not a function
at file:///app/02-not-a-function.mjs:2:22- Cause — something that is not a function is being called. The classic is
data.mapwhen the API returned an object{ items: [...] }rather than an array. It also happens with a typo in a method name and whenimport xis mixed up withimport { x }. - Fix — log the value and its type (
console.log(data),Array.isArray(data)) and use the right field. - Prevention — type the API response; TypeScript reports
Property 'map' does not existbefore the code runs.
const data = { items: [1, 2, 3] };
const list = Array.isArray(data) ? data : data.items;
console.log(list.map((x) => x * 2));[ 2, 4, 6 ].file:///app/03-not-defined.mjs:2
console.log(totl);
^
ReferenceError: totl is not defined
at file:///app/03-not-defined.mjs:2:13
file:///app/03-tdz.mjs:1
console.log(total);
^
ReferenceError: Cannot access 'total' before initialization
at file:///app/03-tdz.mjs:1:13let before its declaration.- Cause —
is not defined— no variable with that name exists in scope (a typo, a missing import, declared in another function).Cannot access … before initialization— thelet/constvariable exists, but its declaration line hasn’t run yet. - Fix — fix the name or the import; move the declaration above the first use.
- Prevention — the editor and TypeScript underline undeclared names; the
no-use-before-definelint rule catches the second case.
Async and network: await, promises, fetch, JSON, CORS
/app/05-await.cjs:2
const res = await fetch("http://localhost:3101/api/products");
^^^^^
SyntaxError: await is only valid in async functions and the top level bodies of modules- Cause —
awaitis used inside a regular function. Withoutasyncit is only allowed at the top level of an ES module. - Fix — mark the function
async, and have the caller await the result too, withawaitor.then(). - Prevention — write async functions as
async functionfrom the start; it is a syntax error, so the editor shows it.
UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "timeout".- Cause — a promise was rejected and nobody handled it: no
awaitinsidetry/catchand no.catch(). If the rejection reason is anError, Node.js prints that error and its stack, but the process still exits. - Fix — await every promise and handle the error where it is clear what to do with it.
- Prevention — don’t call async functions and drop the promise; the
@typescript-eslint/no-floating-promisesrule finds such calls. More in the article on error handling.
async function loadUser() {
throw new Error("User not found");
}
try {
await loadUser();
} catch (err) {
console.error("Could not load user:", err.message);
}Could not load user: User not found, the process keeps running.<anonymous_script>:1
<!DOCTYPE html><html><body><h1>Not Found</h1></body></html>
^
SyntaxError: Unexpected token '<', "<!DOCTYPE "... is not valid JSON
at JSON.parse (<anonymous>)res.json() received HTML, Node.js 24. Chrome shows the same text.- Cause — the server answered with an HTML page (404, 500, a login page) and the code called
res.json(). The<is the start of<!DOCTYPE html>. Usually the URL is wrong, the API route doesn’t exist or the server crashed. - Fix — check
res.okandContent-Typebefore parsing the body; inspect the URL and response in the Network tab. - Prevention — one
fetchwrapper for the whole project that checks the status and throws a clear error.
import { createServer } from "node:http";
const server = createServer((req, res) => {
res.writeHead(404, { "Content-Type": "text/html" });
res.end("<!DOCTYPE html><html><body><h1>Not Found</h1></body></html>");
}).listen(3101);
async function getJson(url) {
const res = await fetch(url);
const type = res.headers.get("content-type") ?? "";
if (!res.ok || !type.includes("application/json")) {
throw new Error(`${url}: ${res.status} ${res.statusText}, content-type ${type}`);
}
return res.json();
}
try {
await getJson("http://localhost:3101/api/products");
} catch (err) {
console.error(err.message);
} finally {
server.close();
}http://localhost:3101/api/products: 404 Not Found, content-type text/html.[TypeError: fetch failed] {
[cause]: AggregateError [ECONNREFUSED]:
at internalConnectMultiple (node:net:1430:18)
at afterConnectMultiple (node:net:2099:7) {
code: 'ECONNREFUSED',
[errors]: [
Error: connect ECONNREFUSED ::1:3999- Cause — the connection was refused: the API server isn’t running, runs on another port or, in Docker, listens only inside the container. The real reason is always in
cause, not infetch failed. - Fix — start the server and check the host and port; log
err.cause.codein code. - Prevention — keep the API URL in environment variables, not in code; wait for dependencies at startup (for example
depends_onwith a health check in Docker Compose).
try {
await fetch("http://localhost:3999/api/products");
} catch (err) {
console.error(err.message, "->", err.cause?.code);
}fetch failed -> ECONNREFUSED.Access to fetch at 'http://localhost:4101/api/products' from origin 'http://localhost:4100' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
Access to fetch at 'http://localhost:4101/api/products' from origin 'http://localhost:4102' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
TypeError: Failed to fetchcatch.- Cause — a page on one origin (scheme, domain, port) requests an API on another, and the API didn’t send
Access-Control-Allow-Origin. For a request withContent-Type: application/jsonthe browser first sends anOPTIONSpreflight. The code only getsTypeError: Failed to fetch— the browser shows details only in the console. - Fix — set the headers on the API server: allow the specific origin and answer the
OPTIONSpreflight with methods and headers. CORS cannot be fixed in the frontend —mode: 'no-cors'only makes the response unreadable. - Prevention — keep the list of allowed origins in the API config;
*doesn’t work for requests with cookies. In Next.js and Vite you can call your API through the same origin (a Route Handler or the dev server proxy).
createServer((req, res) => {
if (fixed) {
res.setHeader("Access-Control-Allow-Origin", ALLOWED_ORIGIN);
res.setHeader("Vary", "Origin");
if (req.method === "OPTIONS") {
// preflight: which methods and headers the page may send
res.writeHead(204, {
"Access-Control-Allow-Methods": "GET, POST",
"Access-Control-Allow-Headers": "Content-Type",
"Access-Control-Max-Age": "600",
});
return res.end();
}
}
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify([{ id: 1, name: "Espresso Blend 1 kg" }]));
}).listen(4101, () => console.log(`page :4100, api :4101, fixed=${fixed}`));servers.mjs, Node.js http): after it the page received [{"id":1,…}].Node.js and npm: modules, dependencies, ports
/app/cjs-pkg/index.js:1
import { readFileSync } from "node:fs";
^^^^^^
SyntaxError: Cannot use import statement outside a module
file:///app/09-require-in-esm.mjs:1
const fs = require("node:fs");
^
ReferenceError: require is not defined in ES module scope, you can use import instead- Cause —
importin a file Node.js treats as CommonJS (.cjsor"type": "commonjs"), orrequirein an ES module (.mjsor"type": "module"). - Fix — pick one system: in a new project,
"type": "module"inpackage.jsonandimporteverywhere. If an ES module needsrequire, create it withcreateRequirefromnode:module. - Prevention — always set the
typefield. Without it Node.js 24 detectsimportsyntax on its own but prints aMODULE_TYPELESS_PACKAGE_JSONwarning and spends time re-parsing.
Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'dayjs' imported from /app/11-missing-package.mjs
Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/app/utils' imported from /app/11-no-extension.mjs
Did you mean to import "./utils.js"?- Cause —
Cannot find package— the package isn’t innode_modules:npm installwas skipped aftergit pullor run in another folder.Cannot find module … Did you mean— in Node.js ES modules a relative import must include the file extension. - Fix —
npm install package-nameornpm install;./utils.jsinstead of./utilsin the import. - Prevention — commit
package-lock.jsonand install withnpm ciin CI; bundlers (Vite, Next.js) don’t require extensions — the rule applies to running in Node.js.
npm error code ERESOLVE
npm error ERESOLVE unable to resolve dependency tree
npm error
npm error While resolving: shop-front@1.0.0
npm error Found: react@18.3.1
npm error node_modules/react
npm error react@"18" from the root project
npm error
npm error Could not resolve dependency:
npm error peer react@"^19.3.0" from react-dom@19.3.0
npm error node_modules/react-dom
npm error react-dom@"19" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry this command with --force or --legacy-peer-deps to accept an incorrect (and potentially broken) dependency resolution.npm install react@18 react-dom@19, npm 11.19, excerpt.- Cause — a peer dependency conflict:
react-dom@19.3.0requiresreact@^19.3.0, while the project hasreact@18. npm 7+ refuses to build a tree that breaks that requirement. - Fix — align the versions: here
npm install react@19 react-dom@19succeeded. If the conflict comes from a third-party package, update it or wait for a release that supports your React version. - Prevention — don’t fix it with
--forceor--legacy-peer-deps: the npm docs explicitly advise against them, they install an unverified combination. Upgrade related packages together.
Error: listen EADDRINUSE: address already in use :::3001- Cause — another process already listens on the port: a second dev server instance, a stuck previous run or another application.
- Fix — stop the old process or start on another port (
next dev -p 3001,vite --port 5174). Finding the owner on Windows:netstat -ano | findstr :3000, the process id is in the last column. - Prevention — read the port from a
PORTvariable and stop dev servers instead of just closing the terminal window.
npm error Missing script: "dev"
npm error
npm error To see a list of scripts, run:
npm error npm run- Cause —
package.jsonhas no script with that name: the project usesstartorserveinstead ofdev, or the command was run in the wrong folder. - Fix — list the scripts with
npm runand run the right one from the folder that containspackage.json. - Prevention — document the run commands in the project README.
TypeScript: TS2322, TS2339, TS2345, TS18048, TS7006, TS2307
src/errors.ts(4,7): error TS2322: Type 'string' is not assignable to type 'number'.
src/errors.ts(9,14): error TS2339: Property 'data' does not exist on type 'Response'.
src/errors.ts(17,13): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
src/errors.ts(22,13): error TS18048: 'found' is possibly 'undefined'.
src/errors.ts(25,23): error TS7006: Parameter 'items' implicitly has an 'any' type.
src/errors.ts(30,28): error TS2307: Cannot find module './utils/date.js' or its corresponding type declarations.tsc 7.0.2 output with strict: true for one file with six errors.TS2322
- What it means
- The value doesn’t match the declared type: the string
"5"into anumbervariable - How to fix
- Convert explicitly (
Number(...)) or fix the type
TS2339
- What it means
- The type has no such property:
Responsehas nodata - How to fix
- Read the body with
await res.json(); for your own types, add the field
TS2345
- What it means
- The argument’s type doesn’t match the function parameter
- How to fix
- Convert the value before the call; don’t widen the parameter to
any
TS18048
- What it means
- The value may be
undefined:finddoesn’t always find an element - How to fix
- Handle “not found”:
if (!found),?.,??
TS7006
- What it means
- Under
strict, an untyped parameter would get an implicitany - How to fix
- Declare the parameter type
TS2307
- What it means
- The module isn’t found at that path or the package has no types
- How to fix
- Check the path and extension; for an untyped package install
@types/…
type User = { id: number; name: string; email?: string };
// TS2322: convert the value explicitly
const quantity: number = Number("5");
// TS2339: Response has no data — read the body with json()
async function loadUsers(): Promise<User[]> {
const res = await fetch("/api/users");
return (await res.json()) as User[];
}
// TS2345: convert the string before passing it
function formatPrice(price: number) {
return `${price} ₸`;
}
const priceFromInput = "4900";
formatPrice(Number(priceFromInput));
// TS18048: handle the "not found" case
const users: User[] = [{ id: 1, name: "Aigerim" }];
const found = users.find((u) => u.id === 2);
console.log(found?.name ?? "user not found");
// TS7006: describe the parameter type
export function total(items: unknown[]) {
return items.length;
}
export { quantity, loadUsers };tsc --noEmit --strict finished with no errors.React: re-renders, keys and the Rules of Hooks
Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
src/cases/TooManyRenders.tsx(6,18): error TS2322: Type 'void' is not assignable to type 'MouseEventHandler<HTMLButtonElement> | undefined'.tsc before running.- Cause — state is set during render. Almost always it is
onClick={setCount(count + 1)}: the function is called while rendering, not on click. - Fix — pass a function, not the result of calling it:
onClick={() => setCount(count + 1)}. - Prevention — TypeScript catches this as TS2322 (
voidinstead of a handler), the linter with theset-state-in-renderrule.
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Clicked {count} times</button>;
}Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.- Cause — an effect updates state it depends on:
useEffect(() => setFilters({ ...filters, page: 1 }), [filters])creates a new object each time, the dependency changes and the effect runs again. - Fix — move the update into the event handler that causes it, or compute the value during render. If an effect is really needed, depend on a primitive (
filters.category), not on the object. - Prevention — don’t sync one piece of state to another through effects — see the
useEffectarticle.
import { useState } from "react";
export default function Filters() {
const [filters, setFilters] = useState({ category: "coffee", page: 2 });
// reset the page in the same event that changes the category
function changeCategory(category: string) {
setFilters({ category, page: 1 });
}
return (
<p>
<button onClick={() => changeCategory("tea")}>Tea</button> {filters.category}, page{" "}
{filters.page}
</p>
);
}Each child in a list should have a unique "key" prop.
Check the render method of `ProductList`. See https://react.dev/link/warning-keys for more information.key on list items — Chrome 154, a dev-only warning: it’s absent in the production build.- Cause — elements created in
maphave nokeyprop, so React can’t match them between renders. - Fix — use a stable unique id from the data:
key={p.id}. - Prevention — don’t use the array index for lists that are sorted or edited, and never
Math.random(): state inside the rows gets lost.
const products = [
{ id: 1, name: "Espresso Blend 1 kg" },
{ id: 2, name: "Colombia Supremo 250 g" },
];
export default function ProductList() {
return (
<ul>
{products.map((p) => (
<li key={p.id}>{p.name}</li>
))}
</ul>
);
}Error: Objects are not valid as a React child (found: object with keys {name, email}). If you meant to render a collection of children, use an array instead.- Cause — an object was put in JSX:
{user}instead of{user.name}. Rendering aDateor a whole API response looks the same. - Fix — render specific fields, dates via
toLocaleDateString(), and for debuggingJSON.stringify(value). - Prevention — typed props: TypeScript flags an object in JSX right in the editor.
const user = { name: "Aigerim", email: "aigerim@example.com" };
export default function Profile() {
return (
<p>
User: {user.name} ({user.email})
</p>
);
}React has detected a change in the order of Hooks called by Cart. This will lead to bugs and errors if not fixed. For more information, read the Rules of Hooks: https://react.dev/link/rules-of-hooks
Previous render Next render
------------------------------------------------------
1. useState useState
2. undefined useState
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error: Rendered more hooks than during the previous render.return — Chrome 154: a warning and an error.- Cause — a hook isn’t called on every render: after an early
return, inside anifor a loop. React identifies hooks by call order, and the order broke. - Fix — put all hooks at the top of the component, before any conditions and
returns; move the condition inside the hook or into the JSX. - Prevention — the
rules-of-hooksrule (ineslint-plugin-react-hooksand oxlint) finds this before running — the linter output is in the last section.
import { useState } from "react";
export default function Cart({ items }: { items: string[] }) {
const [delivery, setDelivery] = useState("courier");
const [promo, setPromo] = useState(""); // all hooks before any return
if (items.length === 0) {
return <p>Cart is empty</p>;
}
return (
<form>
<input value={promo} onChange={(e) => setPromo(e.target.value)} />
<select value={delivery} onChange={(e) => setDelivery(e.target.value)}>
<option>courier</option>
<option>pickup</option>
</select>
</form>
);
}Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://react.dev/link/invalid-hook-call for tips about how to debug and fix this problem.- Cause — a hook was called outside a component or custom hook body: in a handler, a regular function, a class. Less often, two copies of React or mismatched
reactandreact-domversions. - Fix — call hooks only at the top level of a component or a
useSomethingfunction; check for React copies withnpm ls react. - Prevention — name your hooks with a
useprefix — the linter then checks them by the same rules.
Next.js: hydration, Server and Client Components
Uncaught Error: Hydration failed because the server rendered text didn't match the client. As a result this tree will be regenerated on the client. This can happen if a SSR-ed Client Component used:
- A server/client branch `if (typeof window !== 'undefined')`.
- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called.
- Date formatting in a user's locale which doesn't match the server.
- External changing data without sending a snapshot of it along with the HTML.
- Invalid HTML tag nesting.
It can also happen if the client has a browser extension installed which messes with the HTML before React loaded.
https://react.dev/link/hydration-mismatch
...
<MenuLabel>
<p>
+ Mobile menu
- Desktop menunext dev, Chrome 154, component tree trimmed. The + line is the client, - the server.- Cause — the server HTML didn’t match the first browser render. Here it’s a
typeof windowcheck during render: the server has nowindow, so the text differs.Date.now(),Math.random(), dates in the user’s locale, invalid tag nesting (<div>inside<p>) and browser extensions do the same. - Fix — make the first render identical and read browser-only values in
useEffectafter hydration. For unavoidable differences such as timestamps, usesuppressHydrationWarningon one element. - Prevention — don’t read
window,localStorageor the current time in the component body; use CSS media queries for responsiveness.
"use client";
import { useEffect, useState } from "react";
export default function MenuLabel() {
const [isMobile, setIsMobile] = useState(false); // the same value on the server and on the first client render
useEffect(() => {
setIsMobile(window.innerWidth < 1024); // runs only in the browser, after hydration
}, []);
return <p>{isMobile ? "Mobile menu" : "Desktop menu"}</p>;
}Mobile menu../app/page.tsx:1:10
Error: You're importing a module that depends on `useState` into a React Server Component module. This API is only available in Client Components. To fix, mark the file (or its parent) with the `"use client"` directive.
Learn more: https://nextjs.org/docs/app/api-reference/directives/use-clientnext build, Next.js 16.4, Turbopack.- Cause — in the App Router components are Server Components by default, and
useState,useEffectand event handlers only work in Client Components. - Fix — move the interactive part into its own file with
"use client"as the first line and render it from the server page. - Prevention — keep
"use client"as low in the tree as possible — only on interactive leaves. More in the Server Components article.
"use client";
import { useState } from "react";
export default function CartCounter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Items in cart: {count}</button>;
}next build succeeded and the page was prerendered as static../app/cart-counter.tsx:2:1
Error: The "use client" directive must be placed before other expressions. Move it to the top of the file to resolve this issue.next build, excerpt.- Cause — the directive comes after an
importor other code. It is then just a string and the file stays a Server Component — which is why theuseStateerror follows. - Fix — move
"use client"to the very top of the file, before the imports; comments above it are fine. - Prevention — create Client Components from a template that already has the directive first.
Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
Error: Event handlers cannot be passed to Client Component props.
{onClick: function onClick, children: ...}
^^^^^^^^^^^^^^^^
If you need interactivity, consider converting part of this to a Client Component.onClick in a server page, next build. The same text appears when passing an onBuy function to a Client Component.- Cause — a Server Component passes a function: a handler in JSX or a callback prop to a Client Component. Functions can’t be serialized and sent to the browser.
- Fix — move the handler entirely into the Client Component; for data mutations use a Server Action (a function marked
"use server"). - Prevention — props crossing the server → client boundary must be serializable: strings, numbers, arrays, plain objects.
Error occurred prerendering page "/". Read more: https://nextjs.org/docs/messages/prerender-error
ReferenceError: window is not defined
at <unknown> (app\theme-label.tsx:4:17)
2 |
3 | export default function ThemeLabel() {
> 4 | const theme = window.localStorage.getItem("theme") ?? "light";
| ^next build, a Client Component reads localStorage during render.- Cause — Client Components are rendered on the server too, at build time and on the first request, and there is no
window,documentorlocalStoragethere. - Fix — access browser APIs in
useEffector event handlers; load a browser-only module withnext/dynamicandssr: falsefrom a Client Component. - Prevention —
"use client"doesn’t mean “browser only” — remember that the first render happens on the server.
"use client";
import { useEffect, useState } from "react";
export default function ThemeLabel() {
const [theme, setTheme] = useState("light");
useEffect(() => {
// the effect runs only in the browser, after hydration
setTheme(window.localStorage.getItem("theme") ?? "light");
}, []);
return <p>Theme: {theme}</p>;
}next build succeeded../app/user-badge.tsx:3:1
Error: You're importing a module that depends on "next/headers" into a React Client Component module. This API is only available in Server Components but one of its parents is marked with "use client", so this module is also a Client Component.
Learn more: https://nextjs.org/docs/app/building-your-application/rendering
<Products> is an async Client Component. Only Server Components can be async at the moment. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server.next build) and an async Client Component (next dev, Chrome console).- Cause —
cookies(),headers()and async components thatawaitin their body only work on the server. Most often"use client"was added to a file written as a Server Component. - Fix — remove
"use client"from such a file and pass the data to the Client Component as props; in the browser, load data withuseEffector a data-fetching library. - Prevention — split files: the Server Component fetches data, the Client Component handles interactivity.
./app/page.tsx:1:1
Error: Module not found: Can't resolve '@/components/Header'next build, excerpt.- Cause — there is no file at that path: a typo, different letter case (
header.tsxvsHeader.tsx) or the@/alias points elsewhere. - Fix — check the path and the case; aliases live in
pathsintsconfig.json. TheImport mapline in the error shows what the alias resolved to. - Prevention — Windows and macOS ignore case by default, but Linux on the build server doesn’t: file names and imports must match exactly.
Error: Route "/": Next.js encountered uncached or runtime data during prerendering.
`fetch(...)`, `cookies()`, `headers()`, `params`, `searchParams`, or `connection()` accessed outside of `<Suspense>` prevents the route from being prerendered, blocking the page load and leading to a slower user experience.
Ways to fix this:
- [stream] Provide a placeholder with `<Suspense fallback={...}>` around the data access
- [cache] For uncached data (`fetch`, database calls): cache the access with `"use cache"` (does not apply to `connection()`)
- [block] Set `export const instant = false` to allow a blocking route
Learn more: https://nextjs.org/docs/messages/blocking-prerender-dynamicnext build with Cache Components (enabled in the create-next-app 16.4 template).- Cause — a Server Component awaits
fetchoutside<Suspense>, so Next.js can’t build the page’s static shell. - Fix — wrap the data component in
<Suspense fallback={…}>so the data streams in; if the data needn’t be fresh on every request, cache the function with the"use cache"directive. - Prevention — place the
<Suspense>boundary close to the data access; the Next.js docs advise against disabling the check withinstant = falseunless needed.
import { Suspense } from "react";
async function Products() {
const res = await fetch("https://example.com/api/products");
const products: { id: number; name: string }[] = await res.json();
return <ul>{products.map((p) => <li key={p.id}>{p.name}</li>)}</ul>;
}
export default function Home() {
return (
<main>
<h1>Shop</h1>
<Suspense fallback={<p>Loading products…</p>}>
<Products />
</Suspense>
</main>
);
}next build succeeded and / was built as a Partial Prerender.How to find the answer yourself
Read the whole first line
The error type and the text after the colon matter most. In Node.js the file, line and a
^under the spot are shown above it.Find your file in the stack
The first
atline with your project’s path is where to look. Skipnode:internalandnode_moduleslines.Check the data
Log the value and its type before the failing line; for network errors open the Network tab and check the status and response body.
Search the exact text
Without your variable names and paths, in quotes. Official pages: MDN for JavaScript, react.dev for React, nextjs.org/docs/messages for Next.js.
Reproduce it minimally
A new file or project where the error repeats in 10–20 lines almost always reveals the cause.
Error: Minified React error #301; visit https://react.dev/errors/301 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.src/cases/InvalidHookCall.tsx:5:19: error react-hooks(rules-of-hooks): React Hook "useState" is called in function "getInitialTheme" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".
src/cases/HooksOrder.tsx:9:29: error react-hooks(rules-of-hooks): React Hook "useState" is called conditionally. React Hooks must be called in the exact same order in every component render.
src/cases/MissingKey.tsx:9:17: warning react(jsx-key): Missing "key" prop for element in iterator.help hints are trimmed.- A linter with the React hooks rules and
tsc --noEmitrun before each commit and in CI - API responses are checked for
res.okand content type beforeres.json() - Every promise is awaited or has a
.catch() react,react-domandnextare upgraded together- Browser APIs (
window,localStorage) are read only in effects and handlers - Service URLs and ports live in environment variables
How this was verified7 · passedchecked 12 October 2026
“Run” means the code was executed in a scratch project or container and the output in the article comes from that run. “Partial” means it was checked against stubs instead of external services. “Not run” means it needs a device, an account or a key; the steps were checked against the official documentation. The verification project files and run logs are kept in the InterLAB archive.