isMissingSchemaError function

bool isMissingSchemaError(
  1. PostgrestException e
)

Returns true when e indicates the _schema_meta table does not exist on the target Supabase project — i.e. the schema has never been applied and the caller should offer to bootstrap it.

Matches three shapes:

  1. Postgres 42P01relation "_schema_meta" does not exist. The Postgres-level undefined_table error passed through by PostgREST.
  2. PostgREST PGRST205Could not find the table '…' in the schema cache. The schema-cache miss that PostgREST raises when the table has been created but the schema cache was not reloaded, OR when the table is genuinely missing on newer PostgREST versions.
  3. postgrest-dart HTTP fallback '404' + table-missing message. PostgrestException.fromJson falls back to using the HTTP status code as a string when the response body does not contain a code field. The body may be bare JSON, a gateway 404 page, or an older PostgREST version. To avoid treating every 404 as "schema missing" (a wrong URL beyond our extractProjectRef validation could also land here), we also require the message text to confirm a table-missing semantic.

Intentionally does NOT match:

  • PGRST116 — "JSON object requested, multiple (or no) rows returned". This means the table exists but no row was returned, which is orthogonal to "schema missing". Callers should use .maybeSingle() (which returns null instead of throwing) and handle the null separately from the exception branch.
  • Auth errors (PGRST301, PGRST302, PGRST303) — invalid anon key.
  • Permission errors (42501) — RLS denying the anon role.

Implementation

bool isMissingSchemaError(PostgrestException e) {
  final code = e.code;
  if (code == '42P01' || code == 'PGRST205') return true;
  if (code == '404') {
    final msg = e.message.toLowerCase();
    if (msg.contains('does not exist') ||
        msg.contains('not find the table') ||
        msg.contains('schema cache')) {
      return true;
    }
  }
  return false;
}