bknd-debugging
npx skills add https://github.com/cameronapak/bknd-skills --skill bknd-debugging
Agent 安装分布
Skill 文档
Debugging Common Issues
Diagnose and fix common Bknd problems using CLI tools, error analysis, and systematic troubleshooting.
Prerequisites
- Bknd project set up locally
- Terminal/command line access
- Basic understanding of HTTP status codes
When to Use UI Mode
- Inspecting data in admin panel (
/admin) - Verifying entity schema visually
- Testing CRUD operations manually
- Checking user/role configurations
When to Use Code Mode
- Running debug CLI commands
- Analyzing API response errors
- Checking route registration
- Inspecting configuration paths
- Reviewing server logs
CLI Debug Commands
Show All Registered Routes
npx bknd debug routes
Output shows every HTTP endpoint:
- API routes (
/api/data/*,/api/auth/*,/api/media/*) - Admin routes (
/admin/*) - Custom Flow HTTP triggers
- Plugin routes
Use when: endpoint returns 404, verifying custom routes registered.
Show Internal Paths
npx bknd debug paths
Output:
[PATHS] {
rootpath: '/path/to/bknd',
distPath: '/path/to/dist',
relativeDistPath: './dist',
cwd: '/your/project',
dir: '/path/to/cli',
resolvedPkg: '/path/to/package.json'
}
Use when: config file not loading, path resolution issues.
CLI Help
npx bknd --help
npx bknd run --help
npx bknd types --help
HTTP Error Codes
| Code | Meaning | Common Causes |
|---|---|---|
| 400 | Bad Request | Invalid JSON, missing required fields, validation error |
| 401 | Unauthorized | Missing/invalid/expired token |
| 403 | Forbidden | Valid token but insufficient permissions |
| 404 | Not Found | Wrong endpoint, entity doesn’t exist, record not found |
| 409 | Conflict | Duplicate unique field, user already exists |
| 413 | Payload Too Large | File upload exceeds body_max_size |
| 500 | Server Error | Unhandled exception, database error |
Common Issues & Solutions
Config File Not Loading
Symptoms: “Config file could not be resolved” error
Diagnose:
# Check config exists
ls bknd.config.*
# Check current directory
pwd
# Check what bknd sees
npx bknd debug paths
Solutions:
# Ensure correct extension
mv bknd.config.js bknd.config.ts
# Specify explicitly
npx bknd run -c ./bknd.config.ts
# Check supported extensions: .ts, .js, .mjs, .cjs, .json
Database Not Persisting
Symptoms: Data disappears on server restart
Diagnose:
# Check if using memory mode
# Look for "Using in-memory" in startup output
npx bknd run
# Check for database file
ls *.db
Solutions:
# Use file-based database
npx bknd run --db-url "file:data.db"
# NOT memory mode
npx bknd run --memory # Data will be lost!
# Verify in config:
# connection: { url: "file:data.db" } â
# connection: { url: ":memory:" } â
Port Already in Use
Symptoms: EADDRINUSE: address already in use
Diagnose:
# Find process using port
lsof -i :3000
# Or on Windows
netstat -ano | findstr :3000
Solutions:
# Use different port
npx bknd run --port 3001
# Kill existing process
kill -9 <PID>
# Or on Windows
taskkill /PID <PID> /F
Authentication Not Working
Symptoms: 401 errors, token not persisting, user always null
Diagnose:
# Test login endpoint
curl -X POST http://localhost:3000/api/auth/password/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"password"}'
# Check auth configuration
# Look for "strategy" in response errors
Solutions:
- Auth not enabled:
export default {
app: {
auth: { enabled: true }, // Required!
}
}
- Wrong strategy path:
# Password auth endpoint:
POST /api/auth/password/login # â
POST /api/auth/login # â 404
- JWT secret not set (production):
auth: {
jwt: {
secret: process.env.JWT_SECRET, // Required for production
}
}
- Cookie not set (CORS):
auth: {
cookie: {
secure: false, // Set true only for HTTPS
sameSite: "lax", // Not "strict" for OAuth
}
}
- Token not persisting (frontend):
const api = new Api({
host: "http://localhost:3000",
storage: localStorage, // Required for token persistence
});
Permission Denied (403)
Symptoms: Valid token but 403 Forbidden
Diagnose:
# Check user's role
curl http://localhost:3000/api/auth/me \
-H "Authorization: Bearer <token>"
# Check role permissions in config
Solutions:
- Guard not enabled:
export default {
app: {
auth: {
guard: { enabled: true }, // Required for permissions
}
}
}
- No default role (anonymous access):
auth: {
guard: {
roles: {
anonymous: {
is_default: true, // Allow unauthenticated access
permissions: ["data.entity.read"],
}
}
}
}
- Role missing permission:
roles: {
user: {
permissions: [
"data.entity.read",
"data.entity.create", // Add if needed
]
}
}
- Entity-specific permission needed:
permissions: [
{ permission: "data.entity.read", entity: "posts" },
]
Entity/Record Not Found (404)
Symptoms: 404 on data endpoints
Diagnose:
# List all entities
curl http://localhost:3000/api/data
# Check entity name (case-sensitive)
curl http://localhost:3000/api/data/Posts # â
curl http://localhost:3000/api/data/posts # â
# Verify routes
npx bknd debug routes | grep data
Solutions:
- Schema not synced:
# Restart server to sync schema
npx bknd run
- Entity name case mismatch:
// Schema defines lowercase
entity("posts", { ... })
// API call must match exactly
api.data.readMany("posts"); // â
api.data.readMany("Posts"); // â 404
- Record doesn’t exist:
const result = await api.data.readOne("posts", 999);
if (!result.ok) {
console.log("Not found:", result.status); // 404
}
Type Errors with em()
Symptoms: TypeScript errors using schema object
Problem: em() returns schema definition, NOT queryable EntityManager.
// WRONG - this will fail
const schema = em({
posts: entity("posts", { title: text() }),
});
schema.repo("posts").find(); // â Error!
// CORRECT - use SDK for queries
const api = new Api({ url: "http://localhost:3000" });
await api.data.readMany("posts"); // â
For direct database access (server-side only):
const app = new App(config);
await app.build();
const posts = await app.em.repo("posts").findMany(); // â
Schema Sync Issues
Symptoms: Entity exists in code but not in database, or vice versa
Diagnose:
# Check admin panel -> Schema view
# Or query directly
curl http://localhost:3000/api/system/schema
Solutions:
- Restart server – schema syncs on startup:
npx bknd run
- Force sync (may drop data):
options: {
sync: {
force: true, // Dangerous! Can drop tables
}
}
- Check mode – Database Mode ignores code schema:
// Code Mode (default) - schema from code
mode: "code"
// Hybrid Mode - merges code + database
mode: "hybrid"
File Upload Failing
Symptoms: 413 error, upload silently fails
Diagnose:
# Check file size
ls -la myfile.jpg
# Test upload
curl -X POST http://localhost:3000/api/media/upload \
-H "Authorization: Bearer <token>" \
-F "file=@myfile.jpg"
Solutions:
- File too large:
media: {
body_max_size: 10 * 1024 * 1024, // 10MB
}
- Storage not configured:
media: {
adapter: {
type: "s3",
// ... S3 config
}
}
- Local storage (dev only):
import { registerLocalMediaAdapter } from "bknd/adapter/node";
const local = registerLocalMediaAdapter();
export default {
app: {
media: { adapter: local }
}
}
CORS Errors
Symptoms: “Access-Control-Allow-Origin” errors in browser console
Diagnose:
# Check CORS headers
curl -I http://localhost:3000/api/data/posts \
-H "Origin: http://localhost:5173"
Solutions:
export default {
app: {
server: {
cors: {
origin: ["http://localhost:5173", "https://myapp.com"],
credentials: true, // For cookies
}
}
}
}
For development (allow all):
server: {
cors: {
origin: "*",
}
}
Headless Environment Crash
Symptoms: spawn xdg-open ENOENT on server without display
Solution:
npx bknd run --no-open
Windows ESM Errors
Symptoms: ERR_UNSUPPORTED_ESM_URL_SCHEME on Windows
Solutions:
- Use Node.js 18+
- Ensure
"type": "module"in package.json - Use
.mjsextension for config
TypeScript Types Not Updating
Symptoms: IDE shows old types, autocomplete wrong
Solutions:
# Regenerate types
npx bknd types
# Restart TypeScript server (VS Code)
# Cmd/Ctrl + Shift + P -> "TypeScript: Restart TS Server"
# Clear cache
rm -rf node_modules/.cache
Debug Script Pattern
Create a debug helper for systematic troubleshooting:
// debug.ts
import { Api } from "bknd/client";
async function debug() {
const api = new Api({ host: "http://localhost:3000" });
// 1. Check server health
console.log("=== Health Check ===");
const entities = await fetch("http://localhost:3000/api/data");
console.log("Status:", entities.status);
console.log("Entities:", await entities.json());
// 2. Check auth
console.log("\n=== Auth Check ===");
const me = await api.auth.me();
console.log("Auth status:", me.ok ? "authenticated" : "not authenticated");
if (me.data) console.log("User:", me.data);
// 3. Check schema
console.log("\n=== Schema Check ===");
const schema = await fetch("http://localhost:3000/api/system/schema");
console.log("Schema:", await schema.json());
// 4. Test entity access
console.log("\n=== Entity Access ===");
const posts = await api.data.readMany("posts", { limit: 1 });
console.log("Posts access:", posts.ok ? "success" : `failed (${posts.status})`);
}
debug().catch(console.error);
Run with:
npx tsx debug.ts
Logging Patterns
Server-Side Logging
// In seed function or plugin
options: {
seed: async (ctx) => {
console.log("[SEED] Starting...");
console.log("[SEED] Entities:", Object.keys(ctx.em.entities));
try {
await ctx.em.mutator("posts").insertOne({ title: "Test" });
console.log("[SEED] Created post");
} catch (e) {
console.error("[SEED] Error:", e);
}
}
}
API Response Logging
const api = new Api({
host: "http://localhost:3000",
verbose: true, // Logs all requests/responses
});
// Or manual logging
const result = await api.data.readMany("posts");
console.log("Request result:", {
ok: result.ok,
status: result.status,
data: result.data,
error: result.error,
});
Custom Fetcher with Logging
const api = new Api({
host: "http://localhost:3000",
fetcher: async (url, options) => {
console.log("â", options?.method || "GET", url);
const start = Date.now();
const response = await fetch(url, options);
console.log("â", response.status, `(${Date.now() - start}ms)`);
return response;
},
});
Flow/Task Debugging
HTTP Trigger Errors
Sync mode returns errors in response:
{
"success": false,
"errors": [
{
"task": "fetchUser",
"error": "Failed to fetch user: 404 Not Found",
"timestamp": "2024-01-15T10:30:00Z"
}
]
}
Task Error Handling
import { Task, Condition } from "bknd/flows";
const flow = new Flow("myFlow", [
mainTask,
errorTask.connect(mainTask, Condition.error()), // Handle errors
]);
Verification Checklist
When debugging, check these in order:
-
Server running?
curl http://localhost:3000/api/data -
Config loaded?
- Check startup logs for “Using config from”
-
Schema synced?
- Check admin panel or
/api/system/schema
- Check admin panel or
-
Auth enabled? (if needed)
- Check
auth: { enabled: true }in config
- Check
-
Permissions set? (if 403)
- Check
guard: { enabled: true }and roles
- Check
-
CORS configured? (if browser errors)
- Check
server: { cors: {...} }
- Check
DOs and DON’Ts
DO:
- Check server logs first
- Use
npx bknd debug routesfor 404s - Verify entity names match exactly (case-sensitive)
- Test with curl before debugging frontend
- Use
verbose: truein Api for request logging - Restart server after schema changes
DON’T:
- Assume
em()returns a queryable EntityManager - Forget
--no-openon headless servers - Use
:memory:database for persistent data - Skip checking HTTP status codes in responses
- Ignore CORS when debugging frontend issues
- Use
sync: { force: true }in production
Related Skills
- bknd-local-setup – Initial project setup
- bknd-env-config – Environment variables
- bknd-setup-auth – Authentication configuration
- bknd-assign-permissions – Permission troubleshooting
- bknd-api-discovery – Explore available endpoints