JuliusBrussee/caveman · error
postgres: inspect tenant tables
Error message
postgres: inspect tenant tables: %w
What it means
ValidateTenantSchema opens a transaction and runs catalog queries to enumerate the tenant schema's tables. This error wraps any failure while executing inspectTenantTables against pg_catalog during that inspection. It means the introspection query itself failed (connection, permissions, or query error), not that the schema is wrong.
Solutions
- Verify the Postgres role used by the pool has permission to read catalog tables (SELECT on information_schema.tables, pg_catalog.pg_class, etc.)
- Check the underlying wrapped error (%w) for context canceled / connection errors and fix connectivity or increase startup timeouts
- Confirm the DSN points to the correct Postgres instance and version
- Retry pool creation if the cause was a transient network failure
Example fix
// before pool, err := NewRuntimePool(ctx, cfg) // fails: postgres: inspect tenant tables // after // grant catalog read to the app role first, then: // GRANT SELECT ON information_schema.tables TO app_role; pool, err := NewRuntimePool(ctx, cfg)
Defensive patterns
Strategy: try-catch
Validate before calling
if err := pool.Ping(ctx); err != nil { return fmt.Errorf("db unreachable before pool init: %w", err) } Try / catch
if err := NewRuntimePool(ctx, cfg); err != nil {
var opErr *pgconn.ConnectError
if errors.As(err, &opErr) || errors.Is(err, context.DeadlineExceeded) {
// retry with backoff or fail startup with a clear message
}
return err
} Prevention
- Grant the app DB role catalog read privileges as part of provisioning
- Use generous startup context timeouts for pool initialization
- Ping the database before creating the runtime pool
When it happens
Trigger: Calling NewRuntimePool (which calls ValidateTenantSchema) when the catalog query in inspectTenantTables cannot be executed: the tx.Query in inspectTenantTables returns an error such as canceled context, permission denied on system catalogs, or a driver/connection failure.
Common situations: Database user lacks SELECT on pg_catalog/information_schema; context canceled mid-startup because the pool init is slow or shut down; transient network drop between Begin and the inspection query; misconfigured DSN pointing at a non-Postgres server that rejects 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
- postgres: inspect tenant foreign keys
- postgres: begin tenant schema inspection
- postgres: inspect resolver schema
- postgres: inspect runtime identity
- postgres: parse DATABASE_URL
AI-assisted analysis of JuliusBrussee/caveman@3ee70a1026 (2026-09-20).
Data as JSON: /api/errors/6af40bafa9156105.
Report an issue: GitHub.
Appendix: source
Thrown at shared/platform/postgresconfig/postgresconfig.go:238
var organizationPolicyExpression = regexp.MustCompile(`^organization_id=\(*current_setting\('app\.current_organization_id'(?:::text)?(?:,true)?\)\)*(?:::[A-Za-z_][A-Za-z0-9_.$"]*)?$`)
// ValidateTenantSchema proves structural isolation invariants that are easy to
// regress during schema evolution. Every tenant table must fail closed under
// FORCE RLS, and every foreign-key edge between tenant tables must carry the
// shared organization scope (plus project scope when both tables have it).
func ValidateTenantSchema(ctx context.Context, pool *pgxpool.Pool) error {
tx, err := pool.BeginTx(ctx, pgx.TxOptions{
IsoLevel: pgx.RepeatableRead,
AccessMode: pgx.ReadOnly,
})
if err != nil {
return fmt.Errorf("postgres: begin tenant schema inspection: %w", err)
}
defer tx.Rollback(ctx)
tables, err := inspectTenantTables(ctx, tx)
if err != nil {
return fmt.Errorf("postgres: inspect tenant tables: %w", err)
}
foreignKeys, err := inspectTenantForeignKeys(ctx, tx)
if err != nil {
return fmt.Errorf("postgres: inspect tenant foreign keys: %w", err)
}
if violations := tenantSchemaViolations(tables, foreignKeys); len(violations) > 0 {
return fmt.Errorf("postgres: tenant schema isolation incomplete: %s", strings.Join(violations, "; "))
}
if err := validateResolverSchema(ctx, tx); err != nil {
return err
}
if err := tx.Commit(ctx); err != nil {
return fmt.Errorf("postgres: finish tenant schema inspection: %w", err)
}
return nil
}
func inspectTenantTables(ctx context.Context, queryer catalogQuerier) ([]tenantTableSchema, error) {View on GitHub (pinned to 3ee70a1026)