KitRocket

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:

  1. Open .env.example to see all required variables
  2. Compare with your .env.local
  3. 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:

  1. Check your Supabase project is active (free tier pauses after 1 week of inactivity)
  2. Verify the connection string format:
DATABASE_URL="postgresql://postgres.[project-ref]:[password]@aws-0-[region].pooler.supabase.com:6543/postgres"
  1. Common mistakes:

    • Wrong password (check for special characters that need URL encoding)
    • Wrong port (use 6543 for the transaction pooler, not 5432)
    • Project reference typo
  2. 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:

  1. Run the build locally to see errors:
pnpm build
  1. 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 definition
    • Argument of type 'X' is not assignable — update the type or add a type assertion
  2. 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() or Math.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:

  1. Check that the API key is set and valid
  2. Verify you're using the correct API endpoint URL
  3. Check if you're behind a corporate firewall or VPN that blocks the request
  4. Look at the full error — it often includes a cause property 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?

On this page