Use when encountering Bknd errors, getting error messages, something not working, or needing quick fixes. Covers error code reference, quick solutions, and common mistake patterns.
npx claudepluginhub cameronapak/bknd-expert --plugin bknd-research-skillsThis skill uses the workspace's default tool permissions.
Quick-reference guide for resolving Bknd errors by error code, symptom, or common mistake pattern.
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`.
Quick-reference guide for resolving Bknd errors by error code, symptom, or common mistake pattern.
Cause: Invalid request body or parameters
Quick fixes:
# Check JSON validity
echo '{"title":"Test"}' | jq .
# Verify Content-Type header
curl -X POST http://localhost:3000/api/data/posts \
-H "Content-Type: application/json" \
-d '{"title":"Test"}'
Common causes:
Content-Type: application/json headerCause: Missing or invalid authentication
Quick fixes:
// Check token exists
console.log(localStorage.getItem("bknd_token"));
// Verify token with /me endpoint
const me = await api.auth.me();
console.log(me.ok ? "Valid" : "Invalid/expired");
Common causes:
storage: localStorage in Api config)expires config)Bearer <token>)credentials: "include")Fix pattern:
const api = new Api({
host: "http://localhost:3000",
storage: localStorage, // Required for token persistence
});
Cause: Authenticated but insufficient permissions
Quick fixes:
# Check user's role
curl http://localhost:3000/api/auth/me \
-H "Authorization: Bearer <token>"
Common causes:
Fix pattern:
auth: {
guard: {
enabled: true,
roles: {
user: {
permissions: [
"data.entity.read",
"data.entity.create", // Add missing permission
]
}
}
}
}
Cause: Endpoint or record doesn't exist
Quick fixes:
# List available routes
npx bknd debug routes
# List entities
curl http://localhost:3000/api/data
# Check entity name case (must match exactly)
curl http://localhost:3000/api/data/posts # lowercase
Common causes:
Posts vs posts)/api/auth/login vs /api/auth/password/login)Cause: Duplicate value or constraint violation
Quick fixes:
// Check for existing record before create
const exists = await api.data.readOneBy("users", { email });
if (!exists.ok) {
await api.data.createOne("users", { email, ... });
}
Common causes:
Cause: File upload exceeds size limit
Fix:
media: {
body_max_size: 50 * 1024 * 1024, // 50MB
}
Cause: Unhandled server exception
Quick fixes:
# Check server logs for stack trace
# Look for error details in response body
curl http://localhost:3000/api/data/posts 2>&1 | jq .error
Common causes:
Wrong:
const schema = em({
posts: entity("posts", { title: text() }),
});
schema.repo("posts").find(); // Error!
Correct:
// em() is for schema definition only
const schema = em({
posts: entity("posts", { title: text() }),
});
// Use SDK for queries
const api = new Api({ host: "http://localhost:3000" });
await api.data.readMany("posts");
Wrong:
POST /api/auth/login # 404
POST /api/auth/register # 404
Correct:
POST /api/auth/password/login # For password strategy
POST /api/auth/password/register
POST /api/auth/google/login # For Google OAuth
Symptom: Token not persisting, logged out after refresh
Wrong:
const api = new Api({
host: "http://localhost:3000",
});
Correct:
const api = new Api({
host: "http://localhost:3000",
storage: localStorage, // Or sessionStorage
});
Wrong:
import { enum } from "bknd"; // Syntax error - reserved word
Correct:
import { enumm } from "bknd";
entity("posts", {
status: enumm(["draft", "published"]),
});
Wrong:
import { primary } from "bknd"; // Not exported in v0.20.0
Correct:
// Primary keys are auto-generated
// To customize format:
entity("posts", { title: text() }, { primary_format: "uuid" });
Wrong:
permissions: [{
permission: "data.entity.read",
filter: { user_id: { $eq: "@user.id" } }, // Wrong prefix
}]
Correct:
permissions: [{
permission: "data.entity.read",
filter: { user_id: { $eq: "@auth.user.id" } }, // Correct prefix
}]
Symptom: Data disappears on restart
Wrong:
npx bknd run --memory
# Or config: { url: ":memory:" }
Correct:
npx bknd run --db-url "file:data.db"
# Or config: { url: "file:data.db" }
Symptom: Permissions not working, everyone has access
Wrong:
auth: {
guard: {
roles: { ... } // Guard not enabled!
}
}
Correct:
auth: {
guard: {
enabled: true, // Required!
roles: { ... }
}
}
Symptom: Auth works in Postman but not browser
Fix:
// Server config
server: {
cors: {
origin: ["http://localhost:5173"],
credentials: true,
}
}
auth: {
cookie: {
secure: false, // false for HTTP dev
sameSite: "lax", // Not "strict" for OAuth
}
}
// Client fetch
fetch(url, { credentials: "include" });
Symptom: RLS filter returns all records instead of filtering
Wrong:
permissions: [{
permission: "data.entity.read",
effect: "allow", // Won't filter!
condition: { user_id: { $eq: "@auth.user.id" } },
}]
Correct:
permissions: [{
permission: "data.entity.read",
effect: "filter", // Filters results
filter: { user_id: { $eq: "@auth.user.id" } },
}]
curl http://localhost:3000/api/data
npx bknd debug routes
npx bknd debug paths
# Login
curl -X POST http://localhost:3000/api/auth/password/login \
-H "Content-Type: application/json" \
-d '{"email":"test@example.com","password":"password"}'
# Check token
curl http://localhost:3000/api/auth/me \
-H "Authorization: Bearer <token>"
# Unauthenticated
curl http://localhost:3000/api/data/posts
# Authenticated
curl http://localhost:3000/api/data/posts \
-H "Authorization: Bearer <token>"
curl http://localhost:3000/api/system/schema
| Issue | Solution |
|---|---|
| Config not loading | Check file name: bknd.config.ts |
| Port in use | npx bknd run --port 3001 |
| Types outdated | npx bknd types |
| Hot reload not working | Restart server |
| Issue | Solution |
|---|---|
| JWT errors | Set JWT_SECRET env var (32+ chars) |
| Cookie not set | secure: true for HTTPS |
| 500 errors | Check logs, set NODE_ENV=production |
| D1 not found | Check wrangler.json bindings |
| Issue | Solution |
|---|---|
| Cold start slow | Use edge-compatible DB (D1, Turso) |
| File upload fails | Use S3/R2, not local storage |
| SQLite native error | Use LibSQL or PostgreSQL |
# Check file exists
ls bknd.config.*
# Specify explicitly
npx bknd run -c ./bknd.config.ts
# Find process
lsof -i :3000
# Use different port
npx bknd run --port 3001
# Headless server - disable browser open
npx bknd run --no-open
# Check for memory mode in output
# Use file database
npx bknd run --db-url "file:data.db"
"type": "module" to package.json.mjs extension for configCheck import paths:
// SDK client
import { Api } from "bknd/client";
// Schema builders
import { em, entity, text } from "bknd";
// Adapters
import { serve } from "bknd/adapter/node"; // Node
import { serve } from "bknd/adapter/cloudflare"; // CF Workers
DO:
npx bknd debug routes for 404sDON'T:
em() for runtime queries:memory: for persistent datastorage: localStorage in Apienabled: true for guard@user.id (use @auth.user.id)