Common Errors
Solutions for the most common KitRocket errors you'll encounter during development and deployment.
"Module not found" errors
Symptom: Build or dev server fails with Cannot find module 'xxx'.
Cause: Dependencies not installed or corrupted node_modules.
Fix:
pnpm install
If that doesn't work, clean install:
rm -rf node_modules .next pnpm-lock.yaml
pnpm install
If the error points to a specific path like @/components/ui/button, check that the file exists. The @/ alias maps to src/, so the file should be at src/components/ui/button.tsx.
"Missing required environment variable"
Symptom: App crashes on startup with Missing required environment variable: X.
Cause: A variable in .env.local is missing or empty.
Fix:
- Open
.env.exampleto see all required variables - Compare with your
.env.local - Fill in any missing values
# Quick check — diff the two files
diff <(grep -oP '^[A-Z_]+' .env.example | sort) <(grep -oP '^[A-Z_]+' .env.local | sort)
After adding variables, restart the dev server — Next.js doesn't hot-reload env changes.
Database connection errors
Symptom: Error: connect ECONNREFUSED or Error: password authentication failed.
Cause: Invalid DATABASE_URL, wrong credentials, or Supabase project paused.
Fix:
- Check your Supabase project is active (free tier pauses after 1 week of inactivity)
- Verify the connection string format:
DATABASE_URL="postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres"
-
Common mistakes:
- Wrong password (check for special characters that need URL encoding)
- Wrong port (use
6543for the transaction pooler, not5432) - Project reference typo
-
Test the connection:
pnpm db:push
Build errors on pnpm build
Symptom: TypeScript errors or module resolution failures during pnpm build.
Cause: TypeScript strictness catches issues that pnpm dev ignores.
Fix:
- Run the build locally to see errors:
pnpm build
-
Fix each TypeScript error. Common ones:
Type 'string | undefined' is not assignable to type 'string'— add a null check or use!Property 'x' does not exist— check the type definitionArgument of type 'X' is not assignable— update the type or add a type assertion
-
If the error is about environment variables, make sure they're available at build time. Server-only variables work in API routes and server components but not in client components.
Hydration mismatch warnings
Symptom: Console warning: Text content does not match server-rendered HTML.
Cause: Server and client render different HTML. Common triggers:
- Browser extensions injecting HTML
- Using
Date.now()orMath.random()in render - Timezone differences between server and client
- Theme detection (dark/light mode)
Fix:
For browser extensions, test in an incognito window.
For dynamic content, use useEffect to set values only on the client:
"use client";
import { useState, useEffect } from "react";
function Timestamp() {
const [time, setTime] = useState<string>("");
useEffect(() => {
setTime(new Date().toLocaleString());
}, []);
return <span>{time}</span>;
}
For theme providers, add suppressHydrationWarning to the <html> tag:
<html lang="en" suppressHydrationWarning>
"NEXT_REDIRECT" error in API routes
Symptom: Error: NEXT_REDIRECT thrown inside a try/catch block.
Cause: Next.js redirect() works by throwing a special error. If you catch it, the redirect breaks.
Fix: Re-throw redirect errors:
import { redirect } from "next/navigation";
try {
// your code
redirect("/dashboard");
} catch (error) {
if (error instanceof Error && error.message === "NEXT_REDIRECT") {
throw error;
}
// handle other errors
}
Or structure your code so redirect() is called outside try/catch.
Port 3000 already in use
Symptom: Error: listen EADDRINUSE: address already in use :::3000.
Cause: Another process is occupying port 3000.
Fix:
# Find the process
lsof -ti:3000
# Kill it
lsof -ti:3000 | xargs kill -9
# Or run on a different port
pnpm dev --port 3001
"TypeError: fetch failed" in API routes
Symptom: External API calls (DodoPayments, Resend, etc.) fail with fetch errors.
Cause: Network issue, invalid URL, or missing API key.
Fix:
- Check that the API key is set and valid
- Verify you're using the correct API endpoint URL
- Check if you're behind a corporate firewall or VPN that blocks the request
- Look at the full error — it often includes a
causeproperty with more details:
try {
const response = await fetch(url);
} catch (error) {
console.error("Fetch failed:", error);
console.error("Cause:", (error as any).cause);
}
"ReferenceError: window is not defined"
Symptom: Server component tries to access browser APIs.
Cause: Code that uses window, document, localStorage, or other browser APIs is running on the server.
Fix: Move browser-only code to a client component:
"use client";
import { useEffect } from "react";
function MyComponent() {
useEffect(() => {
// Safe to use browser APIs here
const stored = localStorage.getItem("key");
}, []);
}
Or use dynamic imports with ssr: false:
import dynamic from "next/dynamic";
const BrowserOnlyComponent = dynamic(() => import("./my-component"), {
ssr: false,
});
Still stuck?
- Check the Auth Issues page for authentication problems
- Check the Payment Issues page for checkout problems
- Check the Deployment Issues page for hosting problems
- Ask in the Telegram community for help