Use when troubleshooting Bknd issues, debugging errors, fixing common problems, or diagnosing why something isn't working. Covers CLI debug commands, error codes, logging, common issues and solutions.
npx claudepluginhub cameronapak/bknd-expert --plugin bknd-research-skillsThis skill uses the workspace's default tool permissions.
Diagnose and fix common Bknd problems using CLI tools, error analysis, and systematic troubleshooting.
Searches, retrieves, and installs Agent Skills from prompts.chat registry using MCP tools like search_skills and get_skill. Activates for finding skills, browsing catalogs, or extending Claude.
Searches prompts.chat for AI prompt templates by keyword or category, retrieves by ID with variable handling, and improves prompts via AI. Use for discovering or enhancing prompts.
Checks Next.js compilation errors using a running Turbopack dev server after code edits. Fixes actionable issues before reporting complete. Replaces `next build`.
Diagnose and fix common Bknd problems using CLI tools, error analysis, and systematic troubleshooting.
/admin)npx bknd debug routes
Output shows every HTTP endpoint:
/api/data/*, /api/auth/*, /api/media/*)/admin/*)Use when: endpoint returns 404, verifying custom routes registered.
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.
npx bknd --help
npx bknd run --help
npx bknd types --help
| 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 |
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
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:" } ✗
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
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:
export default {
app: {
auth: { enabled: true }, // Required!
}
}
# Password auth endpoint:
POST /api/auth/password/login # ✓
POST /api/auth/login # ✗ 404
auth: {
jwt: {
secret: process.env.JWT_SECRET, // Required for production
}
}
auth: {
cookie: {
secure: false, // Set true only for HTTPS
sameSite: "lax", // Not "strict" for OAuth
}
}
const api = new Api({
host: "http://localhost:3000",
storage: localStorage, // Required for token persistence
});
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:
export default {
app: {
auth: {
guard: { enabled: true }, // Required for permissions
}
}
}
auth: {
guard: {
roles: {
anonymous: {
is_default: true, // Allow unauthenticated access
permissions: ["data.entity.read"],
}
}
}
}
roles: {
user: {
permissions: [
"data.entity.read",
"data.entity.create", // Add if needed
]
}
}
permissions: [
{ permission: "data.entity.read", entity: "posts" },
]
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:
# Restart server to sync schema
npx bknd run
// Schema defines lowercase
entity("posts", { ... })
// API call must match exactly
api.data.readMany("posts"); // ✓
api.data.readMany("Posts"); // ✗ 404
const result = await api.data.readOne("posts", 999);
if (!result.ok) {
console.log("Not found:", result.status); // 404
}
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(); // ✓
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:
npx bknd run
options: {
sync: {
force: true, // Dangerous! Can drop tables
}
}
// Code Mode (default) - schema from code
mode: "code"
// Hybrid Mode - merges code + database
mode: "hybrid"
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:
media: {
body_max_size: 10 * 1024 * 1024, // 10MB
}
media: {
adapter: {
type: "s3",
// ... S3 config
}
}
import { registerLocalMediaAdapter } from "bknd/adapter/node";
const local = registerLocalMediaAdapter();
export default {
app: {
media: { adapter: local }
}
}
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: "*",
}
}
Symptoms: spawn xdg-open ENOENT on server without display
Solution:
npx bknd run --no-open
Symptoms: ERR_UNSUPPORTED_ESM_URL_SCHEME on Windows
Solutions:
"type": "module" in package.json.mjs extension for configSymptoms: 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
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
// 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);
}
}
}
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,
});
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;
},
});
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"
}
]
}
import { Task, Condition } from "bknd/flows";
const flow = new Flow("myFlow", [
mainTask,
errorTask.connect(mainTask, Condition.error()), // Handle errors
]);
When debugging, check these in order:
Server running?
curl http://localhost:3000/api/data
Config loaded?
Schema synced?
/api/system/schemaAuth enabled? (if needed)
auth: { enabled: true } in configPermissions set? (if 403)
guard: { enabled: true } and rolesCORS configured? (if browser errors)
server: { cors: {...} }DO:
npx bknd debug routes for 404sverbose: true in Api for request loggingDON'T:
em() returns a queryable EntityManager--no-open on headless servers:memory: database for persistent datasync: { force: true } in production