Skip to main content

Common Issues

This guide covers the most common issues you might encounter when using Geni and how to resolve them.
Error message:
No database url found, please set the DATABASE_URL environment variable
Cause: The DATABASE_URL environment variable is not set or is empty.Solution: Set the DATABASE_URL environment variable before running any Geni command:
# For PostgreSQL
DATABASE_URL="postgres://[email protected]:5432/app?sslmode=disable" geni up

# For MySQL
DATABASE_URL="mysql://root:password@localhost:3306/app" geni up

# For SQLite
DATABASE_URL="sqlite://./database.sqlite" geni up
Alternatively, export it in your shell:
export DATABASE_URL="postgres://[email protected]:5432/app"
geni up
Error message:
Didn't find any files ending with .up.sql at ./migrations. Does the path exist?
Cause: The migrations folder is empty or doesn’t exist, or you’re running Geni from the wrong directory.Solution:
  1. Create your first migration:
DATABASE_URL="your_db_url" geni new create_users_table
  1. If migrations exist elsewhere, set the correct path:
DATABASE_MIGRATIONS_FOLDER="./db/migrations" geni up
  1. Verify the migrations folder exists:
ls -la ./migrations
Error message:
Failed to connect to database: connection timeout
Cause: Database is not running, incorrect connection string, or network issues.Solution:
  1. Verify the database is running:
# For PostgreSQL
pg_isready -h localhost -p 5432

# For MySQL
mysqladmin ping -h localhost

# For Docker containers
docker ps | grep postgres
  1. Increase the wait timeout:
DATABASE_WAIT_TIMEOUT=60 geni up
  1. Check your connection string format matches your database:
  • PostgreSQL: postgres://user:password@host:port/database
  • MySQL: mysql://user:password@host:port/database
  • MariaDB: mariadb://user:password@host:port/database
  • SQLite: sqlite://./path/to/file.db
  • LibSQL: https://your-instance.turso.io
Error message:
No rollback file found for 1709123456
Cause: The corresponding .down.sql file is missing for a migration that’s been applied.Solution:
  1. Check if the down migration file exists:
ls migrations/*_*.down.sql
  1. If missing, recreate it with the same timestamp. For migration 1709123456_create_users.up.sql, create:
touch migrations/1709123456_create_users.down.sql
  1. Add the rollback SQL that reverses the up migration:
-- In 1709123456_create_users.down.sql
DROP TABLE users;
Never delete migration files that have been applied to production. Always create down migrations for safe rollbacks.
Error message:
Error: Deadlock detected / Lock wait timeout exceeded
Cause: Migration is trying to modify a table that’s locked by another process, or a long-running migration is blocking others.Solution:
  1. Run migrations outside of transactions for DDL operations that can’t be rolled back:
-- transaction:no
CREATE INDEX CONCURRENTLY idx_users_email ON users(email);
  1. Check for blocking queries:
-- PostgreSQL
SELECT * FROM pg_stat_activity WHERE state = 'active';

-- MySQL
SHOW PROCESSLIST;
  1. Ensure migrations run during low-traffic periods for production databases.
Error message:
Error: Unauthorized / Authentication failed
Cause: Missing or invalid DATABASE_TOKEN for LibSQL/Turso databases.Solution:
  1. Get your Turso database token:
turso db tokens create your-database
  1. Set both DATABASE_URL and DATABASE_TOKEN:
DATABASE_URL="https://your-db.turso.io" \
DATABASE_TOKEN="your-token-here" \
geni up
  1. For local LibSQL instances, ensure the URL matches your server configuration.
Error message:
Skipping dumping database schema: Command not found
Cause: Required database tools (pg_dump, mysqldump, mariadb-dump) are not installed.Solution:
  1. Install the required tools:
# Ubuntu/Debian - PostgreSQL
sudo apt-get install postgresql-client

# Ubuntu/Debian - MySQL
sudo apt-get install mysql-client

# macOS
brew install postgresql mysql-client
  1. Use the slim Docker image if you don’t need schema dumps:
docker run ghcr.io/emilpriver/geni:latest-slim up
  1. Disable schema dumping:
DATABASE_NO_DUMP_SCHEMA=true geni up
SQLite and LibSQL don’t require external tools for schema dumping - it’s handled natively.
Error message:
Error: Invalid migration file name format
Cause: Migration files don’t follow the required naming convention.Solution:Migration files must follow this pattern:
{timestamp}_{name}.{up|down}.sql
Examples:
  • 1709123456_create_users.up.sql
  • 1709123456_create_users.down.sql
  • create_users.up.sql (missing timestamp)
  • 1709123456-create-users.up.sql (using hyphens)
  • 1709123456_create_users.sql (missing direction)
Always use geni new to generate properly named files:
geni new create_users_table

Database-Specific Issues

PostgreSQL

If your PostgreSQL server requires SSL, add sslmode=require to your connection string:
DATABASE_URL="postgres://user:pass@host:5432/db?sslmode=require"
For development, you can disable SSL verification:
DATABASE_URL="postgres://user:pass@host:5432/db?sslmode=disable"
Ensure your database user has CREATEDB privileges:
ALTER USER your_user CREATEDB;
Or connect as a superuser:
DATABASE_URL="postgres://postgres:password@localhost:5432/app"

MySQL/MariaDB

For MySQL 8.0+, you might need to use the legacy authentication:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'password';
FLUSH PRIVILEGES;
Specify the charset in your connection string:
DATABASE_URL="mysql://user:pass@localhost:3306/db?charset=utf8mb4"

SQLite

SQLite doesn’t handle concurrent writes well. Ensure:
  • Only one process is running migrations
  • Close all connections before running migrations
  • Use WAL mode for better concurrency:
PRAGMA journal_mode=WAL;
Use absolute paths or ./ prefix for SQLite files:
# Relative path
DATABASE_URL="sqlite://./database.sqlite"

# Absolute path
DATABASE_URL="sqlite:///var/data/app.db"

Debugging Tips

Enable Verbose Logging

Check pending migrations with verbose output:
DATABASE_URL="your_url" geni status -v
This shows the actual SQL content of pending migrations.

Verify Migration State

Check which migrations have been applied:
-- PostgreSQL, MySQL, MariaDB
SELECT * FROM schema_migrations ORDER BY version;

-- SQLite
SELECT * FROM schema_migrations ORDER BY version;

Test Migrations Locally

  1. Create a test database:
DATABASE_URL="postgres://localhost:5432/test_db" geni create
  1. Run migrations:
DATABASE_URL="postgres://localhost:5432/test_db" geni up
  1. Test rollback:
DATABASE_URL="postgres://localhost:5432/test_db" geni down -a 1
  1. Clean up:
DATABASE_URL="postgres://localhost:5432/test_db" geni drop

Validate Migration Files

Before applying migrations, validate the SQL syntax:
# PostgreSQL
psql -h localhost -U postgres -d your_db --dry-run -f migrations/123_migration.up.sql

# MySQL
mysql -h localhost -u root -p your_db --verbose --force < migrations/123_migration.up.sql

Getting Help

If you’re still experiencing issues:
  1. Check the GitHub issues for similar problems
  2. Verify you’re using the latest version: geni --version
  3. Review your database logs for detailed error messages
  4. Create a minimal reproduction case with a test database

Report an Issue

Found a bug or need help? Open an issue on GitHub with your database type, Geni version, and error message.

Build docs developers (and LLMs) love