Claude-skill-registry bknd-debugging

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.

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/bknd-debugging" ~/.claude/skills/majiayu000-claude-skill-registry-bknd-debugging && rm -rf "$T"
manifest: skills/data/bknd-debugging/SKILL.md
source content

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

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