Summary
stash eql install --supabase (and the --no-operator-family fallback) fails on any non-superuser Postgres role with type eql_v2_encrypted does not exist. On local Supabase the app role is postgres, which is not a superuser (only supabase_admin is), so the supported Supabase EQL install path is broken out of the box.
Environment
stash 0.17.1 · @cipherstash/stack 0.19.0 · bundled EQL eql-2.3.1
- Local Supabase Postgres,
postgres role (non-superuser)
Repro
# DATABASE_URL=postgresql://postgres:postgres@127.0.0.1:54322/postgres
npx stash eql install --supabase
npx stash eql install --supabase --direct --force
npx stash eql install --force # auto-detects non-superuser -> no-operator-family fallback
All fail:
■ Fatal error: Failed to install EQL: type eql_v2_encrypted does not exist
Root cause
The installer runs the whole bundle as a single in-order transaction (stash/dist/bin/main-*.js, install(): BEGIN → client.query(sql) → grants → COMMIT), so statement order is load-bearing. In the no-operator-family bundles the composite type is created after the function/cast that consume it:
stash/dist/sql/cipherstash-encrypt-supabase.sql (identical offsets in cipherstash-encrypt-no-operator-family.sql):
| line |
statement |
| 156 |
CREATE FUNCTION eql_v2.to_stevec_query(e eql_v2_encrypted) ... ← uses the type |
| 178 |
CREATE CAST (eql_v2_encrypted AS eql_v2.stevec_query) ... ← uses the type |
| 201 |
CREATE TYPE public.eql_v2_encrypted AS ( data jsonb ) ← creates it, too late |
The operator-family bundle cipherstash-encrypt.sql is ordered correctly (type at line 38) but requires superuser (for the operator family). So on Supabase (non-superuser) every bundle the CLI selects is broken. The SQL bundle ships with the CLI but originates from encrypt-query-language — the templating that strips the operator-family section to produce the -supabase / -no-operator-family variants also drops the early CREATE TYPE, leaving only the late one.
Suggested fix
Move CREATE TYPE public.eql_v2_encrypted to the top of the -supabase / -no-operator-family bundles (before the function/cast that use it), matching the ordering already used in cipherstash-encrypt.sql.
Workaround
Pre-create just that one IF NOT EXISTS-guarded type, then re-run stash eql install (the CLI still installs all 196 eql_v2 functions):
DO $$ BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_type WHERE typname = 'eql_v2_encrypted') THEN
CREATE TYPE public.eql_v2_encrypted AS (data jsonb);
END IF;
END $$;
Found via a CipherStash integration eval on cipherstash/supabase-nextjs-starter (hono-pg surface). Full report: https://github.com/cipherstash/supabase-nextjs-starter/blob/feat/multi-surface-starters/docs/evals/hono-pg/2026-07-09-bug-eql-supabase-install-ordering.md
Summary
stash eql install --supabase(and the--no-operator-familyfallback) fails on any non-superuser Postgres role withtype eql_v2_encrypted does not exist. On local Supabase the app role ispostgres, which is not a superuser (onlysupabase_adminis), so the supported Supabase EQL install path is broken out of the box.Environment
stash0.17.1 ·@cipherstash/stack0.19.0 · bundled EQLeql-2.3.1postgresrole (non-superuser)Repro
All fail:
Root cause
The installer runs the whole bundle as a single in-order transaction (
stash/dist/bin/main-*.js,install():BEGIN→client.query(sql)→ grants →COMMIT), so statement order is load-bearing. In the no-operator-family bundles the composite type is created after the function/cast that consume it:stash/dist/sql/cipherstash-encrypt-supabase.sql(identical offsets incipherstash-encrypt-no-operator-family.sql):CREATE FUNCTION eql_v2.to_stevec_query(e eql_v2_encrypted) ...← uses the typeCREATE CAST (eql_v2_encrypted AS eql_v2.stevec_query) ...← uses the typeCREATE TYPE public.eql_v2_encrypted AS ( data jsonb )← creates it, too lateThe operator-family bundle
cipherstash-encrypt.sqlis ordered correctly (type at line 38) but requires superuser (for the operator family). So on Supabase (non-superuser) every bundle the CLI selects is broken. The SQL bundle ships with the CLI but originates fromencrypt-query-language— the templating that strips the operator-family section to produce the-supabase/-no-operator-familyvariants also drops the earlyCREATE TYPE, leaving only the late one.Suggested fix
Move
CREATE TYPE public.eql_v2_encryptedto the top of the-supabase/-no-operator-familybundles (before the function/cast that use it), matching the ordering already used incipherstash-encrypt.sql.Workaround
Pre-create just that one
IF NOT EXISTS-guarded type, then re-runstash eql install(the CLI still installs all 196eql_v2functions):Found via a CipherStash integration eval on
cipherstash/supabase-nextjs-starter(hono-pg surface). Full report: https://github.com/cipherstash/supabase-nextjs-starter/blob/feat/multi-surface-starters/docs/evals/hono-pg/2026-07-09-bug-eql-supabase-install-ordering.md