How to Troubleshoot Kaneo Startup Errors: Complete Debugging Guide
Kaneo startup failures almost always trace back to environment misconfiguration, database connectivity issues, or port conflicts, which you can identify by inspecting logs from apps/api/src/database/wait-for-database.ts and validating your .env file against the requirements in apps/api/src/config/index.ts.
Kaneo is an open-source project management platform structured as a pnpm monorepo containing a Hono-based API (@kaneo/api) and a Vite-powered React frontend (@kaneo/web). When the application fails to initialize, the error typically originates in the startup sequence defined in the usekaneo/kaneo repository. Understanding the specific failure points in the source code allows you to resolve issues without guesswork.
Common Kaneo Startup Error Categories
Missing Environment Variables
The API validates required configuration at launch in apps/api/src/config/index.ts. If essential variables are missing or malformed, the process exits immediately.
DATABASE_URL: Must be a valid PostgreSQL connection string.AUTH_SECRET: Must contain at least 32 characters for JWT signing security.KANEO_API_URLandKANEO_CLIENT_URL: Define the base URLs for the API and web frontend; mismatches here cause CORS and routing errors.
Database Connection Failures
The API startup sequence includes a database health check in apps/api/src/database/wait-for-database.ts, which repeatedly pings PostgreSQL before proceeding. Common failures include:
ECONNREFUSED: PostgreSQL is not running or is inaccessible.ETIMEDOUT: Network latency or firewall rules blocking the connection.- Authentication errors: Invalid credentials in
DATABASE_URL.
Migration Errors
The apps/api/src/database/prepare-database-startup.ts module automatically runs Drizzle ORM migrations on startup. Failures occur when:
- The database schema is out of sync with migration files.
- A migration attempts to create a relation that already exists.
- The database user lacks DDL permissions.
Port Conflicts
By default, the API binds to port 1337 and the Vite dev server uses port 5173. If either port is occupied, you will encounter EADDRINUSE errors.
Redis and WebSocket Adapter Issues
If REDIS_URL is configured, the API attempts to initialize the Redis broadcast adapter (apps/api/src/ws/redis-broadcast-adapter.ts). Connection failures fall back to the in-memory broadcast adapter (apps/api/src/ws/in-memory-broadcast-adapter.ts), but explicit Redis configuration errors can still halt startup.
Step-by-Step Debugging Workflow
Follow this sequence to isolate and resolve startup errors.
-
Start the API in isolation to isolate backend issues from frontend problems:
pnpm --filter @kaneo/api devObserve the console for messages from the database waiter and migration runner.
-
Validate environment variables using a quick Node.js sanity check:
node -e " const required = ['KANEO_CLIENT_URL','KANEO_API_URL','AUTH_SECRET','DATABASE_URL']; required.forEach(k => { if (!process.env[k]) console.error('Missing', k); }); "If variables are missing, add them to a
.envfile in the repository root. -
Test database connectivity independently:
psql $DATABASE_URL -c '\l'If this fails, start PostgreSQL or correct the connection string before proceeding.
-
Run migrations manually if the automatic migration failed:
pnpm --filter @kaneo/api db:generate pnpm --filter @kaneo/api db:migrateFix any SQL errors reported in the output, then restart the API.
-
Check for port conflicts:
lsof -i :1337 # API port lsof -i :5173 # Web dev server portTerminate conflicting processes or modify the ports in your
.envfile. -
Verify Redis connectivity (if applicable):
redis-cli -u $REDIS_URL pingIf Redis is unreachable, remove
REDIS_URLfrom the environment to force the in-memory fallback, or start the Redis service. -
Review build artifacts:
pnpm install pnpm lint pnpm buildMissing dependencies or syntax errors from incomplete builds often manifest as startup crashes.
Key Source Files for Startup Troubleshooting
According to the usekaneo/kaneo source code, these files contain the critical startup logic:
| File Path | Purpose | GitHub Link |
|---|---|---|
apps/api/src/config/index.ts |
Loads and validates environment variables, constructs service URLs. | View Source |
apps/api/src/database/wait-for-database.ts |
Implements retry logic to ping PostgreSQL until it becomes reachable. | View Source |
apps/api/src/database/prepare-database-startup.ts |
Executes Drizzle migrations before the server accepts requests. | View Source |
apps/api/src/index.ts |
Entry point that initializes the Hono server, middleware, and routes. | View Source |
apps/web/vite.config.ts |
Configures the dev server proxy to the API; reads VITE_API_URL. |
View Source |
apps/api/src/ws/redis-broadcast-adapter.ts |
Initializes Redis Pub/Sub for multi-instance deployments. | View Source |
When a stack trace appears in your logs, match the file path against this table to understand which subsystem failed.
Code Examples for Startup Validation
Use these snippets to programmatically verify your environment before launching Kaneo.
Check Required Environment Variables:
// scripts/check-env.ts
import { env } from "process";
const REQUIRED = [
"KANEO_CLIENT_URL",
"KANEO_API_URL",
"AUTH_SECRET",
"DATABASE_URL",
] as const;
export function assertEnv() {
const missing = REQUIRED.filter((k) => !env[k]);
if (missing.length) {
throw new Error(
`Missing required env vars: ${missing.join(", ")}`
);
}
if (env.AUTH_SECRET && env.AUTH_SECRET.length < 32) {
throw new Error("AUTH_SECRET must be at least 32 characters");
}
}
Test Database Connectivity:
// scripts/db-ping.ts
import postgres from "postgres";
const connectionString = process.env.DATABASE_URL;
if (!connectionString) throw new Error("DATABASE_URL not set");
const sql = postgres(connectionString);
await sql`SELECT 1`;
console.log("✅ Database connection successful");
await sql.end();
Detect Port Availability:
#!/usr/bin/env bash
# scripts/check-port.sh
PORT=$1
if lsof -i :"$PORT" >/dev/null 2>&1; then
echo "❌ Port $PORT is in use"
exit 1
else
echo "✅ Port $PORT is available"
fi
Summary
- Validate environment first: Ensure
DATABASE_URL,AUTH_SECRET(32+ chars), and URL variables are set inapps/api/src/config/index.ts. - Verify database reachability: The API waits in
apps/api/src/database/wait-for-database.ts; if it times out, check PostgreSQL status and credentials. - Apply pending migrations: Run
pnpm --filter @kaneo/api db:migratemanually ifprepare-database-startup.tsreports schema errors. - Resolve port conflicts: Ensure ports 1337 (API) and 5173 (web) are free, or configure alternatives.
- Check Redis optionally: Only required for multi-instance setups; otherwise, the in-memory adapter loads automatically.
Frequently Asked Questions
Why does Kaneo exit immediately with "Missing required env vars"?
This error originates in apps/api/src/config/index.ts when the application cannot find DATABASE_URL, AUTH_SECRET, KANEO_API_URL, or KANEO_CLIENT_URL. Create a .env file in the repository root with all required variables, ensuring AUTH_SECRET contains at least 32 characters.
How do I fix "EADDRINUSE" errors when starting Kaneo?
The default API port is 1337 and the web dev server uses 5173. Run lsof -i :1337 or lsof -i :5173 to identify the occupying process, terminate it, or change the ports by updating KANEO_API_URL and KANEO_CLIENT_URL in your environment configuration.
What causes "ECONNREFUSED" errors during Kaneo startup?
The API in apps/api/src/database/wait-for-database.ts cannot reach PostgreSQL. Verify that your database server is running and that DATABASE_URL contains the correct host, port, and credentials. Test connectivity independently using psql $DATABASE_URL before launching Kaneo.
How can I manually run migrations if automatic startup migration fails?
Execute pnpm --filter @kaneo/api db:generate to create any pending migration files, followed by pnpm --filter @kaneo/api db:migrate to apply them. Review the SQL output for conflicts (such as "column already exists"), resolve them in your database schema, and then restart the API.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →