Back to list
cameronapak

bknd-debugging

by cameronapak

A no-build, un-bloated stack built upon Web Standards that feels freeing to use and can be deployed anywhere.

23🍴 2📅 Jan 21, 2026

SKILL.md


name: bknd-debugging description: 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.

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

CodeMeaningCommon Causes
400Bad RequestInvalid JSON, missing required fields, validation error
401UnauthorizedMissing/invalid/expired token
403ForbiddenValid token but insufficient permissions
404Not FoundWrong endpoint, entity doesn't exist, record not found
409ConflictDuplicate unique field, user already exists
413Payload Too LargeFile upload exceeds body_max_size
500Server ErrorUnhandled 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:

  1. Auth not enabled:
export default {
  app: {
    auth: { enabled: true },  // Required!
  }
}
  1. Wrong strategy path:
# Password auth endpoint:
POST /api/auth/password/login    # ✓
POST /api/auth/login             # ✗ 404
  1. JWT secret not set (production):
auth: {
  jwt: {
    secret: process.env.JWT_SECRET,  // Required for production
  }
}
  1. Cookie not set (CORS):
auth: {
  cookie: {
    secure: false,     // Set true only for HTTPS
    sameSite: "lax",   // Not "strict" for OAuth
  }
}
  1. 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:

  1. Guard not enabled:
export default {
  app: {
    auth: {
      guard: { enabled: true },  // Required for permissions
    }
  }
}
  1. No default role (anonymous access):
auth: {
  guard: {
    roles: {
      anonymous: {
        is_default: true,  // Allow unauthenticated access
        permissions: ["data.entity.read"],
      }
    }
  }
}
  1. Role missing permission:
roles: {
  user: {
    permissions: [
      "data.entity.read",
      "data.entity.create",  // Add if needed
    ]
  }
}
  1. 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:

  1. Schema not synced:
# Restart server to sync schema
npx bknd run
  1. Entity name case mismatch:
// Schema defines lowercase
entity("posts", { ... })

// API call must match exactly
api.data.readMany("posts");     // ✓
api.data.readMany("Posts");     // ✗ 404
  1. 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:

  1. Restart server - schema syncs on startup:
npx bknd run
  1. Force sync (may drop data):
options: {
  sync: {
    force: true,  // Dangerous! Can drop tables
  }
}
  1. 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:

  1. File too large:
media: {
  body_max_size: 10 * 1024 * 1024,  // 10MB
}
  1. Storage not configured:
media: {
  adapter: {
    type: "s3",
    // ... S3 config
  }
}
  1. 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:

  1. Use Node.js 18+
  2. Ensure "type": "module" in package.json
  3. Use .mjs extension 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:

  1. Server running?

    curl http://localhost:3000/api/data
    
  2. Config loaded?

    • Check startup logs for "Using config from"
  3. Schema synced?

    • Check admin panel or /api/system/schema
  4. Auth enabled? (if needed)

    • Check auth: { enabled: true } in config
  5. Permissions set? (if 403)

    • Check guard: { enabled: true } and roles
  6. CORS configured? (if browser errors)

    • Check server: { cors: {...} }

DOs and DON'Ts

DO:

  • Check server logs first
  • Use npx bknd debug routes for 404s
  • Verify entity names match exactly (case-sensitive)
  • Test with curl before debugging frontend
  • Use verbose: true in Api for request logging
  • Restart server after schema changes

DON'T:

  • Assume em() returns a queryable EntityManager
  • Forget --no-open on 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
  • 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

Score

Total Score

75/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

+10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon