gofr-dev/gofr · error
sql: %w
Error message
sql: %w
What it means
This error wraps any failure that occurs while querying the migrations table via SQL in the GoFr migration framework. getLastMigration issues `SELECT ... FROM gofr_migrations` (getLastSQLGoFrMigration) through the container's SQL datasource and scans the result into an int64. If the query or scan fails (missing table, connection failure, NULL value), the underlying driver error is wrapped with the `sql:` prefix so callers can identify the SQL migration stage.
Source
Thrown at pkg/gofr/migration/sql.go:88
func (d sqlMigrator) checkAndCreateMigrationTable(c *container.Container) error {
if _, err := c.SQL.Exec(createSQLGoFrMigrationsTable); err != nil {
return err
}
if _, err := c.SQL.Exec(createSQLGoFrMigrationLocksTable); err != nil {
return err
}
return d.migrator.checkAndCreateMigrationTable(c)
}
func (d sqlMigrator) getLastMigration(c *container.Container) (int64, error) {
var lastMigration int64
err := c.SQL.QueryRowContext(context.Background(), getLastSQLGoFrMigration).Scan(&lastMigration)
if err != nil {
return -1, fmt.Errorf("sql: %w", err)
}
c.Debugf("SQL last migration fetched value is: %v", lastMigration)
lm2, err := d.migrator.getLastMigration(c)
if err != nil {
return -1, err
}
return max(lastMigration, lm2), nil
}
func (d sqlMigrator) commitMigration(c *container.Container, data transactionData) error {
if data.UsedDatasources[dsSQL] {
dialect := c.SQL.Dialect()
switch dialect {
case mysql, sqlite:View on GitHub (pinned to 187eb24962)
Solutions
- Verify the database is reachable and credentials/DSN in the container config are correct by testing a simple query.
- Run the migration setup so the gofr_migrations table exists (checkAndCreateMigrationTable runs before getLastMigration; confirm it succeeded).
- Inspect the wrapped driver error (%w) for the root cause (e.g. 'connection refused', 'no such table').
- Check network/firewall/proxy between the app and the SQL server.
Example fix
// before: migrations run against a fresh DB with no table and DB may be down
app.Migrate()
// after: pre-check connectivity and let migrations create the table
if err := sqlDB.Ping(); err != nil {
log.Fatalf("database not reachable: %v", err)
}
app.Migrate() Defensive patterns
Strategy: try-catch
Validate before calling
// Go: check SQL connectivity before running migrations
if err := c.SQL.Ping(); err != nil {
return fmt.Errorf("sql unavailable before migration: %w", err)
} Type guard
var sqlDB *sql.DB
db, ok := c.SQL.(*sql.DB)
if !ok || db == nil {
return errors.New("SQL datasource not configured")
} Try / catch
last, err := migrator.getLastMigration(c)
if err != nil {
var pathErr *net.OpError
if errors.As(err, &pathErr) {
// retry / fail fast with connection context
}
return fmt.Errorf("migration state lookup failed: %w", err)
} Prevention
- Ping the SQL datasource during app startup before calling Migrate.
- Keep migrations self-contained: let checkAndCreateMigrationTable create the table on every environment.
- Log the wrapped inner error, not just the outer message, when diagnosing.
- Ensure the DB user has SELECT on gofr_migrations.
When it happens
Trigger: Calling Migration.Run/Migrate with a SQL migrator when c.SQL.QueryRowContext(...).Scan(&lastMigration) fails: database unreachable, credentials wrong, gofr_migrations table absent, or the scanned column is NULL/non-numeric.
Common situations: Fresh database where migrations table was never created; SQL server down or wrong DSN in config; network/firewall blocking the DB; a migration row with NULL version value.
Understand the failure class
Background: "query failed", "%w: SQL error" — wrapped database query errors in Go libraries explained — this error's family across 3 libraries.
Related errors
- failed to execute migration query
- surrealdb: %w
- unsupported db dialect; supported dialects are - mysql, post
- query error
- %w: %s: %w
AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01).
Data as JSON: /api/errors/e133dd651f8dadf4.
Report an issue: GitHub.