PluginBench
Rule

nestjs anti hallucination

via PatrickJS/awesome-cursorrules

Blocks phantom NestJS imports, deprecated patterns, and hallucinated decorators to enforce correct framework usage.

What is nestjs anti hallucination?

This rule prevents AI from generating non-existent NestJS import paths, deprecated package names, and incorrect decorator/module patterns. Use it to catch common hallucinations like @nestjs/core/decorators, @nestjs/bull (replaced by @nestjs/bullmq), and misapplied Express patterns in NestJS controllers.

  • Blocks phantom import paths that don't exist in NestJS (@nestjs/core/decorators, @nestjs/swagger/decorators, @nestjs/typeorm/repository, etc.)
  • Enforces migration from deprecated packages (@nestjs/bull → @nestjs/bullmq, nestjs-redis → @nestjs-modules/ioredis, nestjs-config → @nestjs/config)
  • Prevents deprecated TypeORM patterns (getRepository, getConnection outside of providers)
  • Catches wrong decorator combinations (@Injectable on controllers, @Body in GET handlers, @Controller on services)
  • Enforces type safety by banning `any` types and requiring typed event payloads
  • Prevents hardcoded secrets, database URLs, and configuration values in code

Applies to

File patterns this rule matches.

**/*
Rule definition (reference)

Source of truth, from the repository.

NestJS Anti-Hallucination Rules

These rules OVERRIDE all other generation behavior. Check EVERY line of generated code against these rules.

Banned Imports & Phantom Packages

NEVER import these — they don't exist or are deprecated:

❌ @nestjs/core/decorators    — not a real export path
❌ @nestjs/swagger/decorators — import from @nestjs/swagger directly
❌ @nestjs/typeorm/repository — not a real export path
❌ @nestjs/passport/strategies — import from passport-jwt, passport-local, etc.
❌ @nestjs/bull/decorators     — import from @nestjs/bullmq (bull is legacy)
❌ nestjs-redis               — use @nestjs-modules/ioredis or ioredis directly
❌ @nestjs/cqrs/decorators    — import from @nestjs/cqrs directly
❌ nestjs-config              — use @nestjs/config (official)
❌ nestjs-pino/logger          — import from nestjs-pino directly

Correct import paths:

// ✅ Swagger
import { ApiTags, ApiOperation, ApiResponse } from '@nestjs/swagger';

// ✅ TypeORM
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, DataSource } from 'typeorm';

// ✅ BullMQ (NOT Bull)
import { InjectQueue, Processor, WorkerHost } from '@nestjs/bullmq';

// ✅ Config
import { ConfigService, ConfigModule } from '@nestjs/config';

// ✅ Passport
import { AuthGuard } from '@nestjs/passport';
import { Strategy as JwtStrategy, ExtractJwt } from 'passport-jwt';

// ✅ CQRS
import { CommandHandler, ICommandHandler, EventBus } from '@nestjs/cqrs';

Deprecated Patterns — NEVER Generate These

1. getRepository() outside providers

// ❌ DEPRECATED — removed in TypeORM 0.3+
const repo = getRepository(User);
const user = await getConnection().getRepository(User).find();

// ✅ CORRECT — inject via constructor
constructor(
  @InjectRepository(User)
  private readonly userRepo: Repository<User>,
) {}

2. @nestjs/bull (use @nestjs/bullmq)

// ❌ OLD — @nestjs/bull with @Process decorator
import { Process, Processor } from '@nestjs/bull';
@Processor('queue')
class MyProcessor {
  @Process() async handle(job: Job) {}
}

// ✅ CURRENT — @nestjs/bullmq with WorkerHost
import { Processor, WorkerHost } from '@nestjs/bullmq';
@Processor('queue')
class MyProcessor extends WorkerHost {
  async process(job: Job): Promise<void> {}
}

3. Express-specific middleware mistakes

// ❌ WRONG — Express req/res types in NestJS
import { Request, Response } from 'express';
@Get()
async findAll(@Req() req: Request, @Res() res: Response) {
  res.json(data); // Bypasses interceptors, serialization, exception filters
}

// ✅ CORRECT — Use NestJS decorators, return values
@Get()
async findAll(@Query() query: FindAllQueryDto): Promise<UserResponseDto[]> {
  return this.usersService.findAll(query);
}

// Only use @Res() when streaming files or SSE — add { passthrough: true }
@Get('download')
async download(@Res({ passthrough: true }) res: Response) {
  res.set('Content-Type', 'application/octet-stream');
  return new StreamableFile(stream);
}

4. Wrong decorator combinations

// ❌ WRONG — @Injectable() on a controller
@Injectable()
@Controller('users')
export class UsersController {}

// ❌ WRONG — @Controller() on a service
@Controller()
@Injectable()
export class UsersService {}

// ❌ WRONG — @Body() in a GET handler
@Get()
async findAll(@Body() body: any) {} // GET requests should not have a body

// ❌ WRONG — Both @Param and @Query with same name
@Get(':id')
async findOne(@Param('id') paramId: string, @Query('id') queryId: string) {}

5. class-validator / class-transformer mistakes

// ❌ WRONG — Validation without enabling in main.ts
// (AI often forgets this critical line)
// main.ts MUST have:
app.useGlobalPipes(new ValidationPipe({
  whitelist: true,            // Strip unknown properties
  forbidNonWhitelisted: true, // Throw on unknown properties
  transform: true,            // Auto-transform payloads to DTO instances
  transformOptions: {
    enableImplicitConversion: true,
  },
}));

// ❌ WRONG — Mixing validation decorators with wrong transform
export class CreateUserDto {
  @IsString()
  name: string;

  @IsNumber()
  age: string; // Type mismatch! Decorator says number, type says string
}

// ✅ CORRECT — Types match decorators
export class CreateUserDto {
  @IsString()
  @IsNotEmpty()
  name: string;

  @IsInt()
  @Min(0)
  age: number;
}

6. Async module pitfalls

// ❌ WRONG — useFactory without async when awaiting
TypeOrmModule.forRootAsync({
  useFactory: (config: ConfigService) => ({
    type: 'postgres',
    url: config.get('DATABASE_URL'), // Not awaited, no inject
  }),
})

// ✅ CORRECT
TypeOrmModule.forRootAsync({
  imports: [ConfigModule],
  inject: [ConfigService],
  useFactory: async (config: ConfigService) => ({
    type: 'postgres',
    url: config.getOrThrow<string>('DATABASE_URL'),
    autoLoadEntities: true,
    synchronize: false, // NEVER true in production
  }),
})

Type Safety Rules

NEVER generate any

// ❌ BANNED
catch (error: any) { ... }
const data: any = await response.json();
private cache = new Map<string, any>();

// ✅ REQUIRED
catch (error: unknown) {
  if (error instanceof DomainError) { ... }
  throw error;
}
const data = await response.json() as PaymentGatewayResponse;
private cache = new Map<string, CachedSession>();

NEVER generate untyped event payloads

// ❌ WRONG
eventBus.emit('order.created', { order });

// ✅ CORRECT — Typed events
export class OrderCreatedEvent {
  constructor(
    public readonly orderId: string,
    public readonly userId: string,
    public readonly totalAmount: number,
    public readonly occurredAt: Date = new Date(),
  ) {}
}
eventBus.emit(new OrderCreatedEvent(order.id, order.userId, order.total));

Configuration Safety

NEVER generate hardcoded values for:

  • Database connection strings
  • API keys or secrets
  • Port numbers
  • Feature flags
  • External service URLs

ALWAYS use ConfigService with getOrThrow:

// ❌ WRONG
const port = process.env.PORT || 3000;
const dbUrl = process.env.DATABASE_URL;

// ✅ CORRECT
const port = this.configService.getOrThrow<number>('app.port');
const dbUrl = this.configService.getOrThrow<string>('database.url');

Database Safety

NEVER generate:

// ❌ synchronize: true in production config
// ❌ DROP TABLE or TRUNCATE in migration files
// ❌ Raw SQL without parameterized queries
await this.dataSource.query(`SELECT * FROM users WHERE id = '${userId}'`); // SQL injection!

// ✅ CORRECT
await this.dataSource.query(`SELECT * FROM users WHERE id = $1`, [userId]);

Remember

  • If you're unsure whether a package exists, DO NOT import it. Ask or check.
  • If you're generating a NestJS pattern you haven't seen in the official docs, STOP and reconsider.
  • When in doubt, generate LESS code with correct patterns rather than MORE code with guesses.

Related rules

Official Netlify development rules for serverless, edge, background, and scheduled functions with Blobs and Image CDN support.

**/*
41k
via PatrickJS/awesome-cursorrules

Safety-first, read-only network diagnostics guide for developers troubleshooting connection failures.

**/*
41k
via PatrickJS/awesome-cursorrules

Next.js + TypeScript + shadcn/ui development with Python LLM integration via API routes.

**/*
41k
via PatrickJS/awesome-cursorrules

Next.js with TypeScript and Tailwind UI best practices

**/*.tsx +3
41k
via PatrickJS/awesome-cursorrules

Best practices and folder structure for Next.js App Router development.

**/*
41k
via PatrickJS/awesome-cursorrules

Next.js + Material UI + Tailwind CSS + shadcn/ui + Aeternity UI development guide

**/*
41k
via PatrickJS/awesome-cursorrules