Troubleshooting
Common issues and solutions when working with AuthzKit Tenant Guard.
Installation Issues
Generator Not Running
Problem: Metadata files not generated after prisma generate
Symptoms:
- No
.prisma/tenant-guard/
directory - Missing
meta.json
andmeta.ts
files - TypeScript import errors
Solutions:
Verify generator configuration:
prismagenerator tenantGuard { provider = "@authzkit/prisma-tenant-guard-generator" }
Check package installation:
bashnpm list @authzkit/prisma-tenant-guard # Should show installed version
Regenerate explicitly:
bashnpx prisma generate --generator tenantGuard
Check for errors:
bashnpx prisma generate --verbose
Import Errors
Problem: Cannot import generated metadata
Symptoms:
Module not found
errors- TypeScript compilation failures
- Runtime import errors
Solutions:
Check file exists:
bashls -la .prisma/tenant-guard/ # Should show meta.json and meta.ts
Use correct import syntax:
typescript// ✅ Correct import tenantMeta from '../.prisma/tenant-guard/meta.json' assert { type: 'json' }; // ✅ Alternative for older TypeScript const tenantMeta = require('../.prisma/tenant-guard/meta.json'); // ❌ Incorrect import tenantMeta from '.prisma/tenant-guard/meta.json';
Update TypeScript config:
json{ "compilerOptions": { "resolveJsonModule": true, "allowSyntheticDefaultImports": true } }
Runtime Errors
TenantGuardError: Missing Tenant Field
Problem: AuthzKit throws errors about missing tenant fields
Error Message:
TenantGuardError: Tenant guard: missing tenant field for User.create
Operation: users.create.data
Expected field: tenantId
Causes:
- Using strict mode without explicit tenant fields
- Nested operations missing tenant fields
- Schema design issues
Solutions:
Add explicit tenant field:
typescript// ❌ Missing tenantId await tenantDb.user.create({ data: { email: 'user@example.com', name: 'John Doe' } }); // ✅ Include tenantId await tenantDb.user.create({ data: { tenantId: currentTenantId, email: 'user@example.com', name: 'John Doe' } });
Switch to assist mode (development only):
typescriptconst tenantDb = withTenantGuard(prisma, tenantId, 'assist');
Fix nested operations:
typescript// ❌ Missing tenantId in nested create await tenantDb.todo.create({ data: { tenantId: currentTenantId, title: 'Task', tags: { create: [ { name: 'urgent', color: '#red' } // Missing tenantId ] } } }); // ✅ Include tenantId in nested operations await tenantDb.todo.create({ data: { tenantId: currentTenantId, title: 'Task', tags: { create: [ { tenantId: currentTenantId, name: 'urgent', color: '#red' } ] } } });
TenantGuardError: Tenant Mismatch
Problem: Provided tenant field doesn't match current tenant
Error Message:
TenantGuardError: Tenant guard: tenant mismatch for User.create
Expected: 'tenant-123', Actual: 'tenant-456'
Causes:
- Hardcoded tenant IDs in code
- Incorrect tenant context
- Copy-paste errors
Solutions:
Use dynamic tenant ID:
typescript// ❌ Hardcoded tenant await tenantDb.user.create({ data: { tenantId: 'tenant-123', // Hardcoded email: 'user@example.com' } }); // ✅ Dynamic tenant await tenantDb.user.create({ data: { tenantId: currentTenantId, // From context email: 'user@example.com' } });
Verify tenant context:
typescriptconsole.log('Current tenant:', currentTenantId); console.log('Provided tenant:', data.tenantId);
Cross-tenant Operation Blocked
Problem: Operations fail when trying to connect cross-tenant data
Error Message:
Foreign key constraint violated on the foreign key
Causes:
- Attempting to connect objects from different tenants
- Incorrect relationship setup
- Data corruption
Solutions:
Verify data belongs to same tenant:
typescript// Check before connecting const todo = await tenantDb.todo.findUnique({ where: { id: todoId } }); const tag = await tenantDb.tag.findUnique({ where: { id: tagId } }); if (!todo || !tag) { throw new Error('Object not found in current tenant'); }
Use correct tenant context:
typescript// Ensure both operations use same tenant context const tenantDb = withTenantGuard(prisma, tenantId);
Check relationship configuration:
prismamodel TodoTag { tenantId String todoId Int tagId Int // Verify relationships include tenantId todo Todo @relation(fields: [todoId, tenantId], references: [id, tenantId]) tag Tag @relation(fields: [tagId, tenantId], references: [id, tenantId]) }
Schema Issues
Models Not Included in Metadata
Problem: Some models missing from generated metadata
Symptoms:
- Models without tenant protection
- Empty metadata file
- Unexpected behavior
Causes:
- Models missing
tenantId
field - No composite unique constraints
- Models excluded from generation
Solutions:
Add tenant field and constraints:
prismamodel User { id Int @id @default(autoincrement()) tenantId String // Add this email String @@unique([tenantId, id], map: "tenantId_id") // Add this }
Check exclusions:
prismagenerator tenantGuard { provider = "@authzkit/prisma-tenant-guard-generator" exclude = ["SystemLog"] // Remove if needed }
Verify generation:
bashnpx prisma generate --verbose
Relationship Mapping Errors
Problem: Relationships not properly mapped in metadata
Symptoms:
- Nested operations not validated
- Foreign key errors
- Inconsistent behavior
Causes:
- Missing tenant field in foreign keys
- Incorrect relationship syntax
- Schema design issues
Solutions:
Include tenant in relationships:
prisma// ❌ Missing tenant in foreign key model Post { author User @relation(fields: [authorId], references: [id]) } // ✅ Include tenant in foreign key model Post { author User @relation(fields: [authorId, tenantId], references: [id, tenantId]) }
Verify composite constraints exist:
prismamodel User { @@unique([tenantId, id], map: "tenantId_id") // Required for relationships }
Performance Issues
Slow Operation Validation
Problem: AuthzKit validation adds significant latency
Symptoms:
- Increased response times
- Timeout errors
- Poor user experience
Causes:
- Complex nested operations
- Large payload sizes
- Inefficient metadata
Solutions:
Optimize operation structure:
typescript// ❌ Very nested operation await tenantDb.todo.create({ data: { title: 'Task', tags: { create: [ { tag: { create: { // Deep nesting increases validation time } } } ] } } }); // ✅ Flatter structure const tag = await tenantDb.tag.create({ /* ... */ }); const todo = await tenantDb.todo.create({ data: { title: 'Task', tags: { connect: [{ id: tag.id }] } } });
Cache tenant clients:
typescriptconst tenantClients = new Map(); const getTenantClient = (tenantId: string) => { if (!tenantClients.has(tenantId)) { tenantClients.set(tenantId, withTenantGuard(prisma, tenantId)); } return tenantClients.get(tenantId); };
Use batch operations:
typescript// ❌ Multiple individual operations for (const item of items) { await tenantDb.item.create({ data: item }); } // ✅ Batch operation await tenantDb.item.createMany({ data: items });
Memory Usage Issues
Problem: High memory usage with AuthzKit
Causes:
- Large metadata files
- Memory leaks in tenant clients
- Inefficient caching
Solutions:
Monitor metadata size:
bashls -lh .prisma/tenant-guard/meta.json
Implement client cleanup:
typescript// Clean up tenant clients periodically setInterval(() => { if (tenantClients.size > 1000) { tenantClients.clear(); } }, 300000); // 5 minutes
Use weak references:
typescriptconst tenantClients = new WeakMap();
Development Issues
Auto-injection Not Working
Problem: Expected auto-injection doesn't occur in assist mode
Symptoms:
- Still getting missing tenant field errors
- No warning logs
- Inconsistent behavior
Causes:
- Using strict mode instead of assist
- Configuration errors
- Schema issues
Solutions:
Verify mode setting:
typescript// Ensure using assist mode const tenantDb = withTenantGuard(prisma, tenantId, 'assist');
Check warning handler:
typescriptconst tenantDb = withTenantGuard(prisma, tenantId, { mode: 'assist', meta: tenantMeta, onWarn: (warning) => { console.log('AuthzKit Warning:', warning); // Should show auto-injections } });
Verify metadata includes model:
typescriptconsole.log('Metadata:', Object.keys(tenantMeta));
TypeScript Errors
Problem: TypeScript compilation errors with AuthzKit
Symptoms:
- Type errors in IDE
- Build failures
- Import issues
Solutions:
Update TypeScript config:
json{ "compilerOptions": { "moduleResolution": "node", "esModuleInterop": true, "resolveJsonModule": true } }
Use type assertions if needed:
typescriptconst tenantMeta = require('../.prisma/tenant-guard/meta.json') as TenantMeta;
Check generated types:
bashcat .prisma/tenant-guard/meta.ts
Debugging Tips
Enable Verbose Logging
const tenantDb = withTenantGuard(prisma, tenantId, {
mode: 'assist',
meta: tenantMeta,
onWarn: (warning) => {
console.log(`🔧 AuthzKit ${warning.code}: ${warning.model}.${warning.operation} at ${warning.path}`);
},
onError: (error) => {
console.error(`❌ AuthzKit Error: ${error.code} - ${error.message}`);
console.error('Stack:', error.stack);
}
});
Inspect Metadata
// Check what models are protected
console.log('Protected models:', Object.keys(tenantMeta));
// Check specific model configuration
console.log('User config:', tenantMeta.User);
Test Tenant Isolation
// Quick isolation test
const test = async () => {
const tenant1Db = withTenantGuard(prisma, 'tenant-1');
const tenant2Db = withTenantGuard(prisma, 'tenant-2');
const user1 = await tenant1Db.user.create({
data: { tenantId: 'tenant-1', email: 'test@example.com', name: 'Test' }
});
const crossTenantAccess = await tenant2Db.user.findUnique({
where: { id: user1.id }
});
console.log('Cross-tenant access result:', crossTenantAccess); // Should be null
};
Check Database State
-- Verify tenant data separation
SELECT tenantId, COUNT(*) FROM "User" GROUP BY tenantId;
-- Check foreign key constraints
SELECT tc.constraint_name, tc.table_name, kcu.column_name
FROM information_schema.table_constraints tc
JOIN information_schema.key_column_usage kcu
ON tc.constraint_name = kcu.constraint_name
WHERE tc.constraint_type = 'FOREIGN KEY';
Getting Help
Community Resources
- GitHub Issues: Report bugs and get community help
- Discord: Real-time support from the community
- Documentation: Comprehensive guides and examples
Debugging Information to Include
When reporting issues, include:
- AuthzKit version:
npm list @authzkit/prisma-tenant-guard
- Prisma version:
npx prisma --version
- Node.js version:
node --version
- Minimal reproduction: Code that reproduces the issue
- Error messages: Complete error output
- Schema: Relevant parts of your Prisma schema
- Configuration: AuthzKit configuration being used
Minimal Reproduction Template
// minimal-repro.ts
import { PrismaClient } from '@prisma/client';
import { withTenantGuard } from '@authzkit/prisma-tenant-guard';
import tenantMeta from './.prisma/tenant-guard/meta.json';
const prisma = new PrismaClient();
async function reproduce() {
const tenantDb = withTenantGuard(prisma, 'test-tenant', {
mode: 'assist',
meta: tenantMeta
});
// Add code that reproduces the issue
try {
const result = await tenantDb.user.create({
data: {
email: 'test@example.com',
name: 'Test User'
}
});
console.log('Success:', result);
} catch (error) {
console.error('Error:', error.message);
}
}
reproduce();
Next: Best Practices - Learn production-tested deployment strategies.