JuliusBrussee/caveman · error

postgres: inspect resolver schema

Error message

postgres: inspect resolver schema: %w

What it means

validateResolverSchema runs a catalog/RLS-policy query that aggregates resolver-schema violations (e.g. policies missing WITH CHECK). This error wraps a failure executing that query's Scan. It indicates the resolver-isolation inspection query failed to run, not that a violation was found (that is the sibling 'resolver isolation incomplete' error).

Solutions

  1. Grant the app role access to pg_policies / the policy catalog views queried
  2. Confirm the Postgres version supports the catalog features used (pg_policies requires 9.5+; row-level security 9.5+)
  3. Inspect the wrapped error for context timeout vs SQL error and address accordingly
  4. Retry after transient connection issues
Defensive patterns

Strategy: try-catch

Validate before calling

var v string
if err := db.QueryRow("SELECT extversion FROM pg_extension WHERE extname='plpgsql'").Scan(&v); err != nil { /* verify catalog access / version */ }

Try / catch

if err := NewRuntimePool(ctx, cfg); err != nil {
    if strings.Contains(err.Error(), "inspect resolver schema") {
        // check role access to pg_policies and Postgres version support
    }
    return err
}

Prevention

When it happens

Trigger: ValidateTenantSchema (via NewRuntimePool) calls validateResolverSchema; the aggregate SELECT ... Scan returns an error: missing privileges on pg_policies/policy catalogs, query syntax mismatch on an older Postgres, or a connection/context failure.

Common situations: Running against Postgres < 9.5 or an Aurora/compatibility build lacking pg_policies; restricted role without access to policy catalogs; context deadline during startup; extension/compatibility layer rejecting the query.

Understand the failure class

Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.

Related errors


AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20). Data as JSON: /api/errors/bacb1f4dac1e95f5. Report an issue: GitHub.

Appendix: source

Thrown at shared/platform/postgresconfig/postgresconfig.go:753

			JOIN pg_roles role ON role.rolname=rr.role_name
			CROSS JOIN pg_class c
			JOIN pg_namespace n ON n.oid=c.relnamespace
			JOIN pg_attribute org_col ON org_col.attrelid=c.oid
			  AND org_col.attname='organization_id' AND NOT org_col.attisdropped
			WHERE n.nspname='public' AND c.relkind IN ('r','p')
			  AND has_table_privilege(rr.role_name, c.oid, 'SELECT,INSERT,UPDATE,DELETE')
			  AND NOT EXISTS (
			    SELECT 1 FROM pg_policy policy
			    WHERE policy.polrelid=c.oid
			      AND role.oid=ANY(policy.polroles)
			      AND policy.polqual IS NOT NULL
			      AND policy.polwithcheck IS NOT NULL
			  )
		)
		SELECT coalesce(string_agg(violation, '; ' ORDER BY violation), '') FROM violations
	`).Scan(&violations)
	if err != nil {
		return fmt.Errorf("postgres: inspect resolver schema: %w", err)
	}
	if violations != "" {
		return fmt.Errorf("postgres: resolver isolation incomplete: %s", violations)
	}
	return nil
}

// WithOrg runs fn inside a transaction whose tenant GUC is transaction-local.
// Empty scopes are rejected: tenant work must never degrade to an unscoped
// query when RLS is the hard boundary.
func WithOrg(ctx context.Context, pool *pgxpool.Pool, orgID string, fn func(pgx.Tx) error) error {
	orgID = strings.TrimSpace(orgID)
	if orgID == "" {
		return errors.New("postgres: organization scope is required")
	}
	tx, err := pool.Begin(ctx)
	if err != nil {
		return err

View on GitHub (pinned to 3ee70a1026)