CipherStashDocs
CipherStash CLI

Troubleshooting

Fix common CipherStash CLI errors covering config files, database permissions, EQL installs, Supabase resets, and Drizzle migration issues.

Common errors

ErrorCauseFix
Could not find stash.config.tsNo config file in cwd or parent dirsRun npx stash init (which runs db install automatically), or run npx stash db install directly, or create stash.config.ts manually
databaseUrl is requiredConfig missing databaseUrlAdd databaseUrl to config and check .env is loaded
must be superuser to create an operator familyStandard SQL requires superuserThe CLI falls back to OPE mode automatically on managed databases. Pass --exclude-operator-family if you see this on self-hosted Postgres.
Insufficient database permissionsRole lacks CREATE privilegesConnect as superuser or grant permissions
EQL is already installedeql_v2 schema existsUse --force to reinstall
Encrypt client file not foundpush/validate can't find the file at config.clientSet client in stash.config.ts to the correct path
drizzle-kit generate faileddrizzle-kit not installed or wrong output dirInstall drizzle-kit and set --out to match your Drizzle config
EQL missing after supabase db resetEQL was installed via direct push, not as a migrationRe-run db install --supabase --migration to add EQL to supabase/migrations/. See below.

Permission issues

The install command checks database permissions before running. On managed databases (Supabase, Neon, RDS), the CLI detects a non-superuser role and automatically uses the no-operator-family (OPE) install variant.

If you still see permission errors:

  1. Run npx stash db test-connection to verify your database URL is correct.
  2. Run npx stash db status to check the current EQL state.
  3. Ensure the connected role has CREATE privileges on the database and public schema.
  4. For the pgcrypto extension, the role needs SUPERUSER or extension owner privileges.

Supabase-specific issues

When using --supabase or the automatic Supabase detection:

  • ORDER BY on encrypted columns is not supported. Sort application-side after decrypting.
  • The anon, authenticated, and service_role roles are Supabase-specific. Don't use --supabase on standard PostgreSQL.

Drizzle migration issues

If --drizzle fails:

  1. Ensure drizzle-kit is installed: npm install -D drizzle-kit
  2. Ensure the --out directory matches your drizzle.config.ts output directory.
  3. Check that your Drizzle config is valid by running npx drizzle-kit generate manually.

Encrypting existing columns

When adding encryptedType to a column that already has data, the CLI rewrites ALTER COLUMN ... SET DATA TYPE eql_v2_encrypted statements into a safe ADD COLUMN / DROP COLUMN / RENAME COLUMN sequence. You must backfill the new column with encryptModel in your application code before applying the DROP step on non-empty tables.

Supabase db reset

Why it happens

supabase db reset drops the entire database and reruns only the SQL files in supabase/migrations/. If you installed EQL via direct push (the default before the --migration flag was added), EQL is not in your migrations directory and gets wiped by the reset.

Fix for new installs

Re-run db install and choose the migration-file path:

npx stash db install --supabase --migration

The CLI writes EQL SQL to supabase/migrations/00000000000000_cipherstash_eql.sql. The all-zero timestamp prefix ensures it runs before any user migrations that reference eql_v2_encrypted. After the file is created, supabase db reset will reinstall EQL automatically on every reset.

Upgrade path for existing direct-push installs

If you already ran a direct-push install and your live database is working, your existing install is not broken. To get a migration file going forward without disrupting the live database, run:

npx stash db install --supabase --migration --force

The EQL SQL is idempotent. The --force flag regenerates the install even though EQL is already present. Your live install is unaffected. After this, supabase db reset reinstalls EQL from the migration file.

On this page