🎉 RamAPI v1.0 is now available! Read the Getting Started Guide
Guides
Troubleshooting

Troubleshooting Guide

Common issues, solutions, and FAQs for RamAPI.

Verification Status: All solutions based on verified RamAPI APIs and common Node.js issues

Table of Contents

  1. Installation & Setup
  2. Server Issues
  3. Routing Problems
  4. Middleware Issues
  5. Authentication Problems
  6. Observability Issues
  7. Performance Problems
  8. TypeScript Errors
  9. FAQ

Installation & Setup

Issue: Module not found errors

Error:

Error: Cannot find module 'ramapi'

Solutions:

  1. Ensure RamAPI is installed:
npm install ramapi```
 
2. Check your package.json:
```json
{
  "dependencies": {
    "ramapi": "^0.1.0"
  }
}
  1. Clear node_modules and reinstall:
rm -rf node_modules package-lock.json
npm install

Issue: ESM vs CommonJS errors

Error:

require() of ES Module not supported

Solution:

Add "type": "module" to package.json:

{
  "type": "module"
}

Use ES6 imports:

import { createApp } from 'ramapi';  // ✅ Correct
const { createApp } = require('ramapi');  // ❌ Won't work

Server Issues

Issue: Port already in use

Error:

Error: listen EADDRINUSE: address already in use :::3000

Solutions:

  1. Kill process on port:
# macOS/Linux
lsof -ti:3000 | xargs kill -9
 
# Windows
netstat -ano | findstr :3000
taskkill /PID <PID> /F
  1. Use different port:
app.listen(3001);
  1. Set port from environment:
const port = parseInt(process.env.PORT || '3000');
app.listen(port);

Issue: Server starts but requests hang

Symptoms:

  • Server starts successfully
  • Requests never complete
  • No errors in console

Common Causes:

  1. Missing await next() in middleware:
// ❌ Wrong
app.use(async (ctx, next) => {
  console.log('Before');
  next();  // Missing await!
});
 
// ✅ Correct
app.use(async (ctx, next) => {
  console.log('Before');
  await next();
});
  1. Not calling next() at all:
// ❌ Wrong - request hangs
app.use(async (ctx, next) => {
  console.log('Logging...');
  // Missing next()!
});
 
// ✅ Correct
app.use(async (ctx, next) => {
  console.log('Logging...');
  await next();
});
  1. Not sending response:
// ❌ Wrong - no response sent
app.get('/users', async (ctx) => {
  const users = await getUsers();
  // Missing ctx.json()!
});
 
// ✅ Correct
app.get('/users', async (ctx) => {
  const users = await getUsers();
  ctx.json({ users });
});

Routing Problems

Issue: 404 Not Found

Error:

404 Not Found

Solutions:

  1. Check route path exactly matches:
app.get('/api/users', handler);  // Must request exactly /api/users
  1. Check HTTP method:
app.post('/users', handler);  // Won't match GET /users
  1. Check route order:
// ❌ Wrong order
app.get('/users/:id', getUser);
app.get('/users/me', getMe);  // Never matches! :id catches it
 
// ✅ Correct order
app.get('/users/me', getMe);  // Specific routes first
app.get('/users/:id', getUser);
  1. Check if middleware blocks request:
// Middleware that stops request
app.use(async (ctx, next) => {
  if (someCondition) {
    ctx.status(403);
    ctx.json({ error: 'Forbidden' });
    return;  // Stops here, never reaches routes
  }
  await next();
});

Issue: Route parameters not working

Error:

console.log(ctx.params.id);  // undefined

Solutions:

  1. Use correct parameter syntax:
// ✅ Correct
app.get('/users/:id', handler);  // Use colon (:)
 
// ❌ Wrong
app.get('/users/{id}', handler);  // Don't use braces
app.get('/users/$id', handler);   // Don't use $
  1. Check parameter name matches:
app.get('/users/:userId', (ctx) => {
  console.log(ctx.params.userId);  // Use same name
});

Middleware Issues

Issue: Middleware not executing

Symptoms:

  • Middleware defined but not running
  • console.log in middleware doesn't print

Solutions:

  1. Register middleware before routes:
// ✅ Correct order
app.use(myMiddleware);
app.get('/users', handler);
 
// ❌ Wrong order
app.get('/users', handler);
app.use(myMiddleware);  // Too late!
  1. Check middleware returns properly:
// ❌ Wrong
function myMiddleware() {
  return (ctx: Context, next: () => Promise<void>) => {
    // ...
  };
}
app.use(myMiddleware);  // Missing ()!
 
// ✅ Correct
app.use(myMiddleware());  // Call the function

Issue: Validation not working

Error:

Request body not validated

Solutions:

  1. Ensure validate middleware is registered:
import { validate } from 'ramapi';  // ✅ Import first
 
const schema = z.object({ name: z.string() });
app.post('/users', validate({ body: schema }), handler);
  1. Check Content-Type header:
# ✅ Correct
curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name":"John"}'
 
# ❌ Missing Content-Type
curl -X POST http://localhost:3000/api/users \
  -d '{"name":"John"}'
  1. Verify schema structure:
// ✅ Correct - object wrapper
validate({ body: userSchema })
 
// ❌ Wrong - missing wrapper
validate(userSchema)

Authentication Problems

Issue: "Authorization header missing"

Error:

{ "error": "Authorization header missing" }

Solutions:

  1. Include Authorization header:
curl http://localhost:3000/api/protected \
  -H "Authorization: Bearer YOUR_TOKEN_HERE"
  1. Check header format:
# ✅ Correct format
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
 
# ❌ Wrong formats
Authorization: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...  # Missing "Bearer"
Authorization: Token eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...  # Wrong prefix

Issue: "Invalid token"

Error:

{ "error": "Invalid token" }

Solutions:

  1. Check JWT secret matches:
// Server
const jwtService = new JWTService({ secret: 'secret123' });
 
// Must use same secret!
const token = jwtService.sign({ sub: 'user-id' });
  1. Check token not expired:
const jwtService = new JWTService({
  secret: 'secret',
  expiresIn: 3600,  // 1 hour
});
 
// Token expires after 1 hour!
  1. Verify token format:
// ✅ Valid JWT format
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNryP4J3jVmNHl0w5N_XgL0n3I9PlFUP0THsR8U
 
// ❌ Invalid - missing parts
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9

Observability Issues

Issue: Tracing not working

Symptoms:

  • No trace output in console
  • Jaeger shows no traces

Solutions:

  1. Enable tracing in config:
const app = createApp({
  observability: {
    tracing: {
      enabled: true,  // Must be true!
      exporter: 'console',
    },
  },
});
  1. Check sample rate:
tracing: {
  enabled: true,
  sampleRate: 1.0,  // Must be > 0
}
  1. Verify Jaeger is running:
docker ps | grep jaeger
curl http://localhost:14268/api/traces

Issue: Flow tracking returns 404

Error:

GET /profile/123/waterfall -> 404 Not Found

Solution:

Flow tracking requires tracing to be enabled:

const app = createApp({
  observability: {
    tracing: {
      enabled: true,  // Required!
    },
  },
});
 
app.use(flowTrackingMiddleware());
registerFlowRoutes(app as any);

Performance Problems

Issue: High memory usage

Symptoms:

  • Memory usage keeps growing
  • Server crashes with out of memory

Solutions:

  1. Reduce trace sample rate:
tracing: {
  sampleRate: 0.1,  // Sample only 10%
}
  1. Disable memory profiling:
profiling: {
  enabled: true,
  captureMemory: false,
}
  1. Check for memory leaks:
node --inspect dist/index.js
# Open chrome://inspect
# Take heap snapshots

Issue: Slow responses

Symptoms:

  • Requests take longer than expected
  • High latency

Solutions:

  1. Enable profiling to identify bottlenecks:
observability: {
  profiling: {
    enabled: true,
    slowThreshold: 100,  // Log requests > 100ms
  },
}
  1. Check database queries:
// Add query timing
const start = Date.now();
const users = await db.query('SELECT * FROM users');
console.log(`Query took ${Date.now() - start}ms`);
  1. Add caching:
import Redis from 'ioredis';
const redis = new Redis();
 
app.get('/users', async (ctx) => {
  const cached = await redis.get('users');
  if (cached) {
    ctx.json(JSON.parse(cached));
    return;
  }
 
  const users = await db.query('SELECT * FROM users');
  await redis.setex('users', 60, JSON.stringify(users));
  ctx.json(users);
});

TypeScript Errors

Issue: Type errors with Context

Error:

Property 'user' does not exist on type 'Context'

Solution:

Extend Context type:

declare module 'ramapi' {
  interface Context {
    user?: {
      id: string;
      email: string;
    };
  }
}
 
// Now ctx.user is typed
app.get('/profile', auth, (ctx) => {
  console.log(ctx.user?.email);  // ✅ Type-safe
});

Issue: "Cannot find module" in TypeScript

Error:

Cannot find module 'ramapi' or its corresponding type declarations

Solutions:

  1. Install @types if needed:
npm install -D @types/node
  1. Check tsconfig.json:
{
  "compilerOptions": {
    "moduleResolution": "node",
    "esModuleInterop": true
  }
}
  1. Rebuild:
rm -rf dist
npm run build

FAQ

Q: How do I debug my RamAPI app?

A: Use VS Code debugger or Node inspector:

VS Code launch.json:

{
  "version": "0.2.0",
  "configurations": [
    {
      "type": "node",
      "request": "launch",
      "name": "Debug RamAPI",
      "program": "${workspaceFolder}/src/index.ts",
      "preLaunchTask": "tsc: build - tsconfig.json",
      "outFiles": ["${workspaceFolder}/dist/**/*.js"]
    }
  ]
}

Or use node inspect:

node --inspect-brk dist/index.js
# Open chrome://inspect

Q: How do I handle file uploads?

A: Use multipart/form-data parser:

npm install formidable
npm install -D @types/formidable
import formidable from 'formidable';
 
app.post('/upload', async (ctx) => {
  const form = formidable({ multiples: true });
 
  const [fields, files] = await new Promise((resolve, reject) => {
    form.parse(ctx.req, (err, fields, files) => {
      if (err) reject(err);
      else resolve([fields, files]);
    });
  });
 
  ctx.json({ files });
});

Q: Can I use RamAPI with existing middleware?

A: Only RamAPI middleware works directly. Convert Express/Koa middleware:

// Express middleware
function expressMiddleware(req, res, next) {
  // ...
}
 
// Convert to RamAPI
function ramApiMiddleware(ctx: Context, next: () => Promise<void>) {
  return new Promise((resolve, reject) => {
    expressMiddleware(ctx.req, ctx.res, (err) => {
      if (err) reject(err);
      else next().then(resolve).catch(reject);
    });
  });
}

Q: How do I serve static files?

A: Use a dedicated static file server or middleware:

import { readFile } from 'fs/promises';
import { join } from 'path';
 
app.get('/static/*', async (ctx) => {
  const filePath = ctx.path.replace('/static/', '');
  const fullPath = join(process.cwd(), 'public', filePath);
 
  try {
    const content = await readFile(fullPath);
    ctx.send(content);
  } catch {
    ctx.status(404);
    ctx.text('Not found');
  }
});

Or use nginx for production static file serving.


Q: How do I handle WebSockets?

A: RamAPI focuses on HTTP APIs. Use a separate WebSocket library:

import { WebSocketServer } from 'ws';
 
const wss = new WebSocketServer({ port: 8080 });
 
wss.on('connection', (ws) => {
  ws.on('message', (data) => {
    ws.send(`Echo: ${data}`);
  });
});
 
// Run alongside RamAPI
app.listen(3000);  // HTTP API
// WebSocket on 8080

Q: How do I test my API?

A: See Testing Strategies guide.

Quick example:

import { describe, it, expect } from 'vitest';
 
describe('API', () => {
  it('should return users', async () => {
    const response = await fetch('http://localhost:3000/api/users');
    const data = await response.json();
    expect(data.users).toBeDefined();
  });
});

Q: Production checklist?

A: See Production Setup.

Quick checklist:

  • Set NODE_ENV=production
  • Use strong JWT secrets
  • Enable HTTPS
  • Add rate limiting
  • Set up logging
  • Configure error handling
  • Add health checks
  • Enable observability
  • Set up monitoring
  • Test error scenarios

Getting Help

  • Documentation: Browse complete docs in complete-documentation/
  • Examples: Check examples/ directory for working code
  • Issues: Report bugs on GitHub
  • Verified APIs: All guides marked with ✅ are verified against source code

See Also