Skip to main content

Common Issues

This guide covers frequent issues developers may encounter when working with RLink and their solutions.

Authentication Issues

Cannot Log In - “Invalid Credentials”

Symptoms: Login fails even with correct email and password Possible Causes:
  1. User account doesn’t exist in database
  2. Password hash mismatch
  3. Email not verified (if verification required)
  4. Session configuration issue
Solutions:
1

Verify User Exists

Connect to your database and check:
SELECT id, email, emailVerified FROM users WHERE email = 'user@example.com';
2

Check Better Auth Configuration

Verify environment variables:
BETTER_AUTH_SECRET # Must be at least 32 characters
NEXT_PUBLIC_APP_URL # Must match actual URL
DATABASE_URL # Must be correct
3

Reset Password

Use the “Forgot Password” flow to reset the user’s password
4

Check Browser Console

Open Developer Tools (F12) and check for errors in:
  • Console tab
  • Network tab (look for failed API requests)

Session Expires Immediately

Symptoms: User logs in successfully but is immediately logged out or session expires Possible Causes:
  1. Cookie domain mismatch
  2. HTTPS/HTTP mismatch
  3. NEXT_PUBLIC_APP_URL incorrect
  4. Session secret changed
Solutions:
# Development
NEXT_PUBLIC_APP_URL="http://localhost:3000"

# Production
NEXT_PUBLIC_APP_URL="https://your-domain.com"
URLs must match EXACTLY - including protocol (http/https) and no trailing slash
  1. Open DevTools (F12)
  2. Application tab → Clear storage
  3. Click “Clear site data”
  4. Refresh page and try logging in again

2FA Code Not Accepting

Symptoms: 2FA code rejected even when entered correctly Possible Causes:
  1. Time sync issue between server and authenticator app
  2. Code already used (codes are single-use)
  3. Wrong secret configured
Solutions:
  1. Check Server Time: Ensure server time is accurate
    date # Should match current time
    
  2. Re-setup 2FA:
    • Go to Settings → Security
    • Disable 2FA
    • Re-enable and scan new QR code
    • Test immediately
  3. Use Backup Codes: If provided during setup, use backup codes to access account

Database Issues

”Connection Timeout” Error

Symptoms: Application cannot connect to database Possible Causes:
  1. Database is paused/inactive (Neon)
  2. Wrong connection string
  3. SSL mode not configured
  4. Network/firewall blocking connection
Solutions:
1

Verify Database is Active

Check Neon dashboard - database may be in suspended state. Click to wake it up.
2

Check Connection String

# Must include sslmode=require for Neon
DATABASE_URL="postgresql://user:pass@host.neon.tech/db?sslmode=require"
3

Test Connection

# Install psql if not available
psql "$DATABASE_URL"
If this fails, the issue is with the connection string or network.
4

Check IP Allowlist

If using Neon’s IP allowlist feature:
  • Add your server’s IP address
  • For Vercel, add Vercel’s IP ranges

Migration Errors

Symptoms: drizzle-kit migrate fails with SQL errors Possible Causes:
  1. Migration already applied
  2. Schema conflicts
  3. Manual database changes conflicting with migrations
Solutions:
Connect to database and check:
SELECT * FROM __drizzle_migrations ORDER BY created_at DESC;
This shows which migrations have been applied.
⚠️ WARNING: This will delete all data
# Drop all tables
psql "$DATABASE_URL" -c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"

# Re-run migrations
npx drizzle-kit migrate
If a specific migration fails:
  1. Review the generated SQL in drizzle/ folder
  2. Apply the failing parts manually via psql
  3. Mark migration as applied in __drizzle_migrations table

”Too Many Connections” Error

Symptoms: Database rejects new connections Possible Causes:
  1. Connection pool exhausted
  2. Connections not being closed properly
  3. Too many concurrent API requests
Solutions:
  1. Enable Connection Pooling in Neon dashboard
  2. Check for Connection Leaks:
    // Bad - connection leak
    const db = drizzle(connection);
    // ... never closes
    
    // Good - using singleton pattern
    import { db } from '@/lib/db'; // Reuses connection
    
  3. Implement Connection Limits:
    // lib/db.ts
    const pool = new Pool({
      connectionString: process.env.DATABASE_URL,
      max: 20, // Maximum pool size
    });
    

API Issues

CORS Errors in Browser

Symptoms: CORS policy: No 'Access-Control-Allow-Origin' header Possible Causes:
  1. ALLOWED_ORIGIN environment variable incorrect
  2. Request from wrong origin
  3. Credentials not included in request
Solutions:
1

Verify ALLOWED_ORIGIN

# Must match exact frontend origin
ALLOWED_ORIGIN="https://your-domain.com"
No trailing slash, must include protocol
2

Check Request Origin

In browser DevTools → Network → failed request:
  • Check Origin header in request
  • Should match ALLOWED_ORIGIN
3

Include Credentials

If making API calls from frontend:
fetch('/api/endpoint', {
  credentials: 'include', // Important!
  headers: {
    'Content-Type': 'application/json',
  },
});

500 Internal Server Error

Symptoms: API returns 500 status code Possible Causes:
  1. Unhandled exception in API route
  2. Database query error
  3. Missing environment variable
Solutions:
Development: Check terminal where npm run dev is runningProduction (Vercel):
  1. Go to Vercel dashboard
  2. Select deployment
  3. Click “Functions” tab
  4. View error logs
Wrap API logic in try-catch:
export async function GET(request: Request) {
  try {
    const data = await db.select().from(table);
    return Response.json(data);
  } catch (error) {
    console.error('API Error:', error);
    return Response.json(
      { error: 'Internal server error' },
      { status: 500 }
    );
  }
}
All required variables set in production:
DATABASE_URL
NEXT_PUBLIC_APP_URL
BETTER_AUTH_SECRET
RESEND_API_KEY
# etc.

Rate Limit Exceeded

Symptoms: API returns 429 status code Possible Causes:
  1. Too many requests from same IP/user
  2. Rate limit threshold too low
  3. Infinite loop making requests
Solutions:
  1. Wait and Retry: Rate limits reset after time period
  2. Check for Request Loops:
    // Bad - infinite loop
    useEffect(() => {
      fetchData(); // Re-runs on every render
    });
    
    // Good - runs once
    useEffect(() => {
      fetchData();
    }, []); // Empty dependency array
    
  3. Adjust rate limits: If traffic is legitimate, raise limits in your middleware or edge configuration.

Email Issues

Emails Not Sending

Symptoms: Users don’t receive welcome emails, password resets, etc. Possible Causes:
  1. Invalid Resend API key
  2. Sending domain not verified
  3. Email in spam folder
  4. Resend account limits reached
Solutions:
1

Verify Resend Configuration

RESEND_API_KEY="re_..." # Check in Resend dashboard
RESEND_FROM="RLink <noreply@yourdomain.com>" # Must use verified domain
2

Check Resend Dashboard

  1. Go to resend.com/emails
  2. Check “Logs” for delivery status
  3. Look for error messages
3

Verify Domain

In Resend dashboard:
  • Go to Domains
  • Ensure domain has green checkmark
  • Add DNS records if not verified
4

Check Spam Folder

Test emails often go to spam. Check:
  • Spam/Junk folder
  • Promotions tab (Gmail)

Email Templates Not Rendering

Symptoms: Emails send but look broken or unstyled Possible Causes:
  1. React Email component error
  2. Missing styles
  3. Email client compatibility
Solutions:
  1. Preview Templates Locally:
    npx react-email dev
    
    Open http://localhost:3000 to preview templates
  2. Check Template Syntax:
    // templates/email/welcome.tsx
    import { Html, Head, Body, Container } from '@react-email/components';
    
    export default function WelcomeEmail({ userName }: { userName: string }) {
      return (
        <Html>
          <Head />
          <Body>
            <Container>
              <h1>Welcome, {userName}!</h1>
            </Container>
          </Body>
        </Html>
      );
    }
    
  3. Test Across Email Clients: Use Litmus or similar to test rendering

Performance Issues

Slow Page Load Times

Symptoms: Pages take >3 seconds to load Possible Causes:
  1. Large database queries without pagination
  2. Missing indexes on database
  3. Too many API calls
  4. Large images not optimized
Solutions:
// Bad - loads all records
const projects = await db.select().from(projectsTable);

// Good - paginated
const projects = await db
  .select()
  .from(projectsTable)
  .limit(10)
  .offset((page - 1) * 10);
-- Index frequently queried columns
CREATE INDEX idx_projects_status ON projects(status);
CREATE INDEX idx_leads_created_at ON leads(created_at);
const { data } = useQuery({
  queryKey: ['projects'],
  queryFn: fetchProjects,
  staleTime: 5 * 60 * 1000, // 5 minutes
  cacheTime: 10 * 60 * 1000, // 10 minutes
});
Use Next.js Image component:
import Image from 'next/image';

<Image
  src="/uploads/large-image.jpg"
  alt="Project"
  width={800}
  height={600}
  quality={75} // Reduce quality for faster load
  placeholder="blur" // Show blur while loading
/>

Memory Leaks

Symptoms: Application becomes slow over time, eventual crashes Possible Causes:
  1. Event listeners not cleaned up
  2. Timers not cleared
  3. Large objects kept in memory
Solutions:
// Clean up effect hooks
useEffect(() => {
  const interval = setInterval(() => {
    // Do something
  }, 1000);
  
  return () => clearInterval(interval); // Cleanup!
}, []);

// Remove event listeners
useEffect(() => {
  const handleResize = () => {
    // Handle resize
  };
  
  window.addEventListener('resize', handleResize);
  return () => window.removeEventListener('resize', handleResize);
}, []);

Build & Deployment Issues

Build Fails on Vercel

Symptoms: Deployment fails during build step Possible Causes:
  1. TypeScript errors
  2. Missing environment variables
  3. Dependency issues
Solutions:
1

Run Build Locally

npm run build
This will show the same errors Vercel encounters
2

Fix TypeScript Errors

# Check types
npx tsc --noEmit

# Fix errors or suppress with @ts-ignore (use sparingly)
3

Check Environment Variables

Ensure all required variables are set in Vercel dashboard
4

Clear Build Cache

In Vercel:
  1. Go to Settings
  2. General → Build & Development
  3. Click “Clear Build Cache”
  4. Redeploy

Vercel Function Timeout

Symptoms: API routes timeout after 10 seconds Possible Causes:
  1. Slow database queries
  2. External API calls taking too long
  3. Heavy computation
Solutions:
  1. Optimize Queries: Add indexes, reduce data fetched
  2. Upgrade Vercel Plan: Pro/Enterprise have longer timeouts (60s-900s)
  3. Move to Background Job:
    // Instead of processing in API route
    // Queue job for background processing
    await queue.add('process-data', { dataId });
    

Development Environment Issues

Module Not Found

Symptoms: Import errors like Cannot find module '@/lib/db' Possible Causes:
  1. TypeScript path aliases not configured
  2. Missing dependencies
  3. Wrong import path
Solutions:
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./*"]
    }
  }
}
rm -rf node_modules package-lock.json
npm install
// Wrong
import { db } from 'lib/db';

// Right
import { db } from '@/lib/db';

Hot Reload Not Working

Symptoms: Changes to files don’t trigger page refresh Possible Causes:
  1. File watcher limit reached
  2. Next.js cache issue
  3. Wrong file location
Solutions:
  1. Increase File Watcher Limit (Linux/Mac):
    echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
    sudo sysctl -p
    
  2. Clear Next.js Cache:
    rm -rf .next
    npm run dev
    
  3. Restart Dev Server: Stop and restart npm run dev

Development and deployment edge cases

Preview URLs vs production (Vercel)

Vercel preview deployments get a different hostname on every branch. Set NEXT_PUBLIC_APP_URL (and related auth URLs) to match the environment you are testing. A cookie issued on localhost will not work on a preview URL, and mixing http and https breaks sessions.

Windows vs macOS/Linux

  • Line endings — If scripts fail mysteriously, check Git core.autocrlf and ensure shell scripts use LF where required.
  • Environment variables — In PowerShell, use $env:VAR=value for one-off commands; in Command Prompt, use set VAR=value.
  • Port 3000 — See Getting started for PowerShell and bash commands to free a port.

Database and Neon

  • Cold starts / timeouts — First request after idle can be slower; connection pooling (Neon serverless) or retry logic may be needed for scripts.
  • SSL — Production DATABASE_URL should use sslmode=require (or your provider’s equivalent).
  • drizzle-kit push on production — Can drift from migration history. Prefer generate + migrate for anything that matters.

Cron and secured routes

Scheduled jobs that call /api/cron/* must send the Authorization header (or mechanism) your route expects—typically CRON_SECRET on Vercel. Missing or wrong secrets return 401 or 403 with no obvious UI hint.

CORS and ALLOWED_ORIGIN

Browser calls from another origin to RLink APIs must match ALLOWED_ORIGIN and cookie rules. Symptoms: preflight failures, or 401 with no session cookie. Align the origin with your deployment docs in Deployment.

API clients and cookies

Server-side fetch from Next.js to your own API can omit cookies if you do not forward them. fetch from the browser after login usually includes cookies automatically. For Postman or curl, you must copy session cookies from the browser after login.

Getting more help

If your issue isn’t covered here:

Check Logs

  • Browser console (F12)
  • Server terminal output
  • Vercel deployment logs

Search Issues

Search for similar issues in:
  • Next.js GitHub issues
  • Better Auth documentation
  • Drizzle ORM discussions
When reporting issues, always include:
  • Error message (full stack trace)
  • Steps to reproduce
  • Environment (dev/production)
  • Browser/Node version