Skip to main content
Version: Local Β· In Progress

Troubleshooting Guide

This page covers 20+ common issues organized by category, with symptoms, root causes, and actionable fixes.


Setup Issues​

1. Port 4005 already in use​

Symptom: Error: listen EADDRINUSE: address already in use :::4005 when starting the backend.

Cause: Another process (or a previous crashed instance) is still bound to port 4005.

Fix:

# Find the process using port 4005
lsof -i :4005

# Kill it
kill -9 <PID>

# Or use a one-liner
kill -9 $(lsof -t -i :4005) 2>/dev/null; cd backend && npm run dev

If you need to change the port, set PORT=4006 in your backend/.env file.


2. Database connection refused​

Symptom: Error: connect ECONNREFUSED 127.0.0.1:5432 or Connection to server at "localhost" refused.

Cause: PostgreSQL Docker container is not running.

Fix:

# Start only PostgreSQL (never run full docker-compose up locally)
docker-compose up -d postgres

# Verify it's running
docker-compose ps

# Test connection
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard -c "SELECT 1"

If the container keeps crashing, check logs:

docker-compose logs postgres

Common sub-causes:

  • Docker Desktop not running (start Docker Desktop first)
  • Port 5432 used by a host-installed PostgreSQL (stop it: brew services stop postgresql)
  • Volume corruption (remove and recreate: docker-compose down -v && docker-compose up -d postgres)

3. npm install fails with node-gyp errors​

Symptom: Build errors mentioning node-gyp, bcrypt, or native module compilation failures.

Cause: Missing build tools or Node.js version mismatch.

Fix:

# Ensure you're on Node.js 18+
node --version

# If using nvm
nvm use 18

# Clean install
cd backend && rm -rf node_modules package-lock.json && npm install
cd ../frontend && rm -rf node_modules package-lock.json && npm install

On macOS, ensure Xcode command line tools are installed:

xcode-select --install

4. Environment variables not loading​

Symptom: Tenable Access Key is required or JWT secret must be at least 32 characters errors on startup.

Cause: Missing or malformed backend/.env file.

Fix:

# Check if .env exists
ls -la backend/.env

# Copy from template if missing
cp backend/.env.example backend/.env

# Verify critical variables are set
grep -E "^(JWT_SECRET|DB_PASSWORD|TENABLE_ACCESS_KEY)" backend/.env

Required variables (from backend/src/config/env.ts):

  • JWT_SECRET -- at least 32 characters
  • DB_PASSWORD -- database password
  • TENABLE_ACCESS_KEY -- Tenable.io API access key
  • TENABLE_SECRET_KEY -- Tenable.io API secret key
  • DATABASE_URL -- full PostgreSQL connection string

5. Frontend shows blank white page​

Symptom: http://localhost:3005 shows a blank page with no errors in the browser console.

Cause: Usually a Vite dev server issue or missing environment variables.

Fix:

# Restart the frontend dev server
cd frontend && npm run dev

# If that fails, clean and rebuild
cd frontend && rm -rf node_modules/.vite && npm run dev

Check the browser console for CORS errors -- if the backend URL is wrong, API calls will fail silently. Verify VITE_API_BASE_URL in frontend/.env points to http://localhost:4005/api.


Scanning Issues (AppSec Module)​

6. Assessment stuck in 'queued' status​

Symptom: The assessment shows "Queued" in the UI and never progresses.

Cause: The PentestCoordinator has not picked up the assessment. This can happen if:

  • The backend was restarted while a scan was queued
  • The assessment's target URL fails outbound validation

Fix:

# Check backend logs for errors
cd backend && npm run dev # Watch the console output

# Verify the target URL is reachable from the backend
curl -I <target-url>

If the assessment is stuck, you can reset it via the database:

-- Connect to the database
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard

-- Reset assessment status
UPDATE pentest_assessments SET status = 'queued', started_at = NULL WHERE id = '<assessment-id>';

7. Zero findings after a scan​

Symptom: Scan completes but shows 0 findings.

Cause: Multiple possible causes:

  1. Authentication failure: Test users could not log in to the target
  2. No endpoints discovered: Crawling found no API endpoints
  3. Target unreachable: Network connectivity issues between backend and target
  4. All agents skipped: Budget exhausted before agents could run

Fix:

Check the agent logs in the database:

SELECT agent_name, status, requests_sent, findings_created, error_message
FROM pentest_agent_logs
WHERE assessment_id = '<assessment-id>'
ORDER BY started_at;

Check Phase 0 authentication:

SELECT scan_context->'testUsers' FROM pentest_assessments WHERE id = '<assessment-id>';

Verify the target is accessible from the backend host (especially in Docker/cloud environments where network rules may block outbound traffic).


8. Agent not connecting to target​

Symptom: Agent logs show ECONNREFUSED or ENOTFOUND errors.

Cause: The target URL is unreachable from the backend server.

Fix:

# Test connectivity from the backend host
curl -v <target-url>

# If running in Docker, test from inside the container
docker-compose exec backend curl -v <target-url>

For local targets (e.g., http://localhost:8080), use your machine's IP address or host.docker.internal instead of localhost if the backend runs in Docker.


Authentication Issues​

9. JWT expired / 401 on every request​

Symptom: All API calls return 401 Unauthorized with code INVALID_TOKEN or TOKEN_EXPIRED.

Cause: The access token has expired (default 15-minute lifetime) and the refresh flow failed.

Fix:

  1. Try refreshing: POST /api/auth/refresh (the frontend does this automatically)
  2. If refresh also fails, log in again
  3. Check that JWT_SECRET in .env has not changed since the token was issued -- changing the secret invalidates all existing tokens
# Quick test: log in and get a fresh token
curl -X POST http://localhost:4005/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@company.com","password":"Admin123@same!"}'

10. SSO redirect loop​

Symptom: Clicking "Sign in with Microsoft" endlessly redirects between ThreatWeaver and Microsoft.

Cause: SSO callback URL mismatch or state parameter corruption.

Fix:

  1. Verify the redirect URI in Azure AD app registration matches exactly: https://<backend-url>/api/sso/callback
  2. Check that SSO_REDIRECT_URI in .env matches the Azure AD registered redirect URI
  3. Ensure cookies are not being blocked (SameSite policy issues)
  4. Check the backend logs for specific OAuth2 errors

11. CORS errors in browser console​

Symptom: Access to XMLHttpRequest has been blocked by CORS policy in the browser console.

Cause: The frontend origin is not in the backend's CORS allowlist.

Fix:

Set CORS_ORIGIN in backend/.env to match your frontend URL:

# For local development
CORS_ORIGIN=http://localhost:3005

# For UAT
CORS_ORIGIN=https://dev.threatweaver.ai

# For production (set this when production hosting is confirmed)
# CORS_ORIGIN=https://threatweaver.ai

If you need multiple origins, separate them with commas. Restart the backend after changing .env.


Database Issues​

12. Migration failed​

Symptom: npm run migrate:local fails with SQL errors.

Cause: Schema conflict, missing column, or duplicate migration.

Fix:

# Check migration status
cd backend && npm run migrate:status

# Reset local database (WARNING: destroys all data)
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard \
-c "DROP SCHEMA public CASCADE; CREATE SCHEMA public;"

# Re-run migration
cd backend && npm run migrate:local

If the migration partially applied, you may need to manually fix the schema:

# Connect to the database
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard

# Check what tables exist
\dt

# Check specific table columns
\d+ users

13. Tenant schema not found​

Symptom: 503 Database schema not available or Error: Schema "tenant_xxx" does not exist.

Cause: In multi-tenant mode, the tenant schema has not been provisioned.

Fix:

For local development, ensure DEPLOYMENT_MODE is not set (single-tenant mode uses the public schema):

# Remove or comment out in backend/.env
# DEPLOYMENT_MODE=saas

If you need multi-tenant mode locally, provision the schema:

CREATE SCHEMA IF NOT EXISTS "tenant_mycompany";

Then run migrations targeting that schema.


14. Connection pool exhausted​

Symptom: Error: Cannot acquire connection from pool or requests hanging/timing out.

Cause: Too many open connections, usually from unreleased QueryRunners.

Fix:

# Check active connections
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard \
-c "SELECT count(*) FROM pg_stat_activity WHERE datname = 'tenable_dashboard';"

# Kill idle connections
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard \
-c "SELECT pg_terminate_backend(pid) FROM pg_stat_activity WHERE datname = 'tenable_dashboard' AND state = 'idle' AND pid <> pg_backend_pid();"

If this recurs, look for code paths that create a QueryRunner but do not release it. The setTenantSchema middleware handles this automatically via res.on('finish') and res.on('close') cleanup hooks.


15. TypeORM "relation does not exist" error​

Symptom: QueryFailedError: relation "some_table" does not exist

Cause: The entity is defined but the table was never created (migration was not run).

Fix:

# Run local migrations (includes synchronize for development)
cd backend && npm run migrate:local

# Verify the table exists
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard -c "\dt some_table"

In multi-tenant mode, make sure you are querying the correct schema. Use getTenantAwareRepository() instead of AppDataSource.getRepository().


Frontend Issues​

16. Page not loading after adding a new route​

Symptom: Navigating to a new page shows a blank area or 404-like behavior.

Cause: Missing one of the three required routing pieces.

Fix: Verify all three exist:

  1. Sidebar href in frontend/src/components/Sidebar.tsx -- href: '/my-page'
  2. Route definition in frontend/src/App.tsx -- <Route path="/my-page" ... />
  3. Component import -- the page component is correctly imported

All three path values must match exactly.


17. API calls returning 401 in the frontend​

Symptom: Pages load but data does not appear; network tab shows 401 responses.

Cause: The auth cookie is not being sent with requests.

Fix:

  1. Check that the API client includes credentials: 'include' in fetch/axios config
  2. Verify that CORS_ORIGIN on the backend matches the exact frontend URL (including protocol and port)
  3. Check that cookies are not blocked by browser privacy settings
  4. Try logging in again -- the token may have expired

18. Frontend build fails with TypeScript errors​

Symptom: npm run build in the frontend fails with type errors.

Fix:

cd frontend

# Check for type errors
npx tsc --noEmit

# If it's a dependency issue, clean and reinstall
rm -rf node_modules && npm install

# Build
npm run build

Common causes:

  • Missing type definitions (install @types/... packages)
  • Stale tsconfig.tsbuildinfo (delete it: rm tsconfig.tsbuildinfo)
  • Import path mismatches (check .ts vs .tsx extensions)

19. Backend build fails for Render deployment​

Symptom: npm run build (tsc) succeeds locally but fails on Render.

Cause: Common Render-specific issues:

Fix:

  1. Never add "type": "module" to backend package.json
  2. Keep tsx in devDependencies (not dependencies)
  3. Test the build locally before pushing:
cd backend && rm -rf dist && npm run build && npm start
  1. Check that all imports use .js extensions (TypeScript ESM resolution)
  2. Verify tsconfig.json has "outDir": "dist" and "module": "NodeNext"

20. Vite HMR not working (changes not reflecting)​

Symptom: Code changes in the frontend are not reflected in the browser.

Fix:

# Clear Vite cache
cd frontend && rm -rf node_modules/.vite

# Restart dev server
npm run dev

If HMR is still broken:

  • Check that the file is being saved (auto-save may be disabled)
  • Check the terminal for Vite compilation errors
  • Try a hard refresh in the browser (Cmd+Shift+R / Ctrl+Shift+R)

Performance Issues​

21. Aggregation queries slow (dashboard loading slowly)​

Symptom: Dashboard takes 10+ seconds to load.

Cause: The aggregation.service.ts runs complex queries over large vulnerability datasets without cached results.

Fix:

  1. Check if the cache is working: the service caches KPI results
  2. Check database indexes:
-- Verify indexes exist on commonly queried columns
\d+ vulnerabilities
  1. Check the vulnerability count -- if there are 100,000+ records, consider archiving old data via POST /api/admin/archive

22. Memory usage growing over time​

Symptom: Backend Node.js process memory increases steadily.

Cause: Possible causes include:

  • In-memory caches not expiring (user cache, token revocation cache)
  • Large scan results held in memory

Fix:

# Check Node.js memory usage
node -e "console.log(process.memoryUsage())"

# Set max memory for Node.js
NODE_OPTIONS="--max-old-space-size=2048" npm run dev

The auth middleware caches are bounded:

  • User cache: 30-second TTL per entry
  • Revoked token cache: 5,000 max entries with 60-second cleanup

Quick Diagnostic Commands​

# Check if backend is running
curl http://localhost:4005/api/health

# Check database connectivity
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard -c "SELECT 1"

# Check backend logs (if running with npm run dev)
# Logs appear in the terminal where you started the backend

# Check frontend is accessible
curl http://localhost:3005

# Verify login works
curl -X POST http://localhost:4005/api/auth/login \
-H "Content-Type: application/json" \
-d '{"email":"admin@company.com","password":"Admin123@same!"}'

# Check sync status
curl http://localhost:4005/api/sync/status \
-H "Cookie: token=<your-jwt-token>"

# Database shell
docker-compose exec -T postgres psql -U tenable -d tenable_dashboard