golang-migrate/migrate · error

no schema

Error message

no schema

What it means

ErrNoSchema is the sentinel error returned by the pgx (and pgx v5) drivers when a schema name is required but empty. In pgx, Open/WithInstance derive the schema from Config.SchemaName or the `search_path`/x-no-lock-etc DSN settings; if no schema can be determined, the driver returns ErrNoSchema because migrations must be scoped to a known schema.

Source

Thrown at database/pgx/v5/pgx.go:41

	_ "github.com/jackc/pgx/v5/stdlib"
)

func init() {
	db := Postgres{}
	database.Register("pgx5", &db)
}

var (
	multiStmtDelimiter = []byte(";")

	DefaultMigrationsTable       = "schema_migrations"
	DefaultMultiStatementMaxSize = 10 * 1 << 20 // 10 MB
)

var (
	ErrNilConfig      = fmt.Errorf("no config")
	ErrNoDatabaseName = fmt.Errorf("no database name")
	ErrNoSchema       = fmt.Errorf("no schema")
)

type Config struct {
	MigrationsTable       string
	DatabaseName          string
	SchemaName            string
	migrationsSchemaName  string
	migrationsTableName   string
	StatementTimeout      time.Duration
	MigrationsTableQuoted bool
	MultiStatementEnabled bool
	MultiStatementMaxSize int
}

type Postgres struct {
	// Locking and unlocking need to use the same connection
	conn     *sql.Conn
	db       *sql.DB

View on GitHub (pinned to 01a9643f14)

Solutions

  1. Set Config.SchemaName explicitly (e.g. "public") or include search_path in the DSN: postgres://.../db?search_path=myschema.
  2. If relying on search_path, add it to the connection string's options parameter so Open can derive the schema.
  3. Validate that the schema value is non-empty before constructing Config in multi-tenant code paths.
  4. Match with errors.Is(err, pgx.ErrNoSchema) and surface a clear message about which schema setting is missing.

Example fix

// before
dsn := "postgres://user:pass@host/db"
drv, err := pgx.Open(dsn) // ErrNoSchema if search_path absent
// after
dsn := "postgres://user:pass@host/db?search_path=myschema"
Defensive patterns

Strategy: validation

Validate before calling

if cfg.SchemaName == "" && !strings.Contains(dsn, "search_path") {
    cfg.SchemaName = "public"
}

Type guard

func hasSchema(c *pgx.Config) bool { return c != nil && c.SchemaName != "" }

Try / catch

drv, err := pgx.Open(dsn)
if err != nil {
    if errors.Is(err, pgx.ErrNoSchema) {
        return fmt.Errorf("set SchemaName or add ?search_path=<schema> to the DSN: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: Calling pgx.Open/WithInstance with a Config whose SchemaName is empty and a DSN that does not carry a schema (no search_path in the options and no x-schema-name-style parameter), e.g. `postgres://user:pass@host/db` with &Config{}.

Common situations: Deployments where the app connects with search_path set server-side per role but the migrate DSN is built independently and loses it; forgetting to set SchemaName when the database user's default schema (public) was intentionally renamed; multi-tenant setups where the schema comes from the request context and is sometimes empty.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02). Data as JSON: /api/errors/abc06797170f3719. Report an issue: GitHub.