Troubleshooting
Fix common CipherStash CLI errors covering config files, database permissions, EQL installs, Supabase resets, and Drizzle migration issues.
Common errors
| Error | Cause | Fix |
|---|---|---|
Could not find stash.config.ts | No config file in cwd or parent dirs | Run npx stash init (which runs db install automatically), or run npx stash db install directly, or create stash.config.ts manually |
databaseUrl is required | Config missing databaseUrl | Add databaseUrl to config and check .env is loaded |
must be superuser to create an operator family | Standard SQL requires superuser | The CLI falls back to OPE mode automatically on managed databases. Pass --exclude-operator-family if you see this on self-hosted Postgres. |
Insufficient database permissions | Role lacks CREATE privileges | Connect as superuser or grant permissions |
EQL is already installed | eql_v2 schema exists | Use --force to reinstall |
Encrypt client file not found | push/validate can't find the file at config.client | Set client in stash.config.ts to the correct path |
drizzle-kit generate failed | drizzle-kit not installed or wrong output dir | Install drizzle-kit and set --out to match your Drizzle config |
EQL missing after supabase db reset | EQL was installed via direct push, not as a migration | Re-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:
- Run
npx stash db test-connectionto verify your database URL is correct. - Run
npx stash db statusto check the current EQL state. - Ensure the connected role has
CREATEprivileges on the database andpublicschema. - For the
pgcryptoextension, the role needsSUPERUSERor extension owner privileges.
Supabase-specific issues
When using --supabase or the automatic Supabase detection:
ORDER BYon encrypted columns is not supported. Sort application-side after decrypting.- The
anon,authenticated, andservice_roleroles are Supabase-specific. Don't use--supabaseon standard PostgreSQL.
Drizzle migration issues
If --drizzle fails:
- Ensure
drizzle-kitis installed:npm install -D drizzle-kit - Ensure the
--outdirectory matches yourdrizzle.config.tsoutput directory. - Check that your Drizzle config is valid by running
npx drizzle-kit generatemanually.
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 --migrationThe 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 --forceThe 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.