golang-migrate/migrate · error
could not parse x-no-lock as bool: %w
Error message
could not parse x-no-lock as bool: %w
What it means
The MySQL driver accepts an optional x-no-lock custom parameter to disable the advisory migration lock. When this parameter is present and non-empty, it must parse as a Go bool via strconv.ParseBool (1, t, T, TRUE, true, True, 0, f, F, FALSE, false, False); anything else makes Open return this wrapped error. It is raised inside Open before the database connection is used.
Source
Thrown at database/mysql/mysql.go:241
return config, nil
}
func (m *Mysql) Open(url string) (database.Driver, error) {
config, err := urlToMySQLConfig(url)
if err != nil {
return nil, err
}
customParams, err := extractCustomQueryParams(config)
if err != nil {
return nil, err
}
noLockParam, noLock := customParams["x-no-lock"], false
if noLockParam != "" {
noLock, err = strconv.ParseBool(noLockParam)
if err != nil {
return nil, fmt.Errorf("could not parse x-no-lock as bool: %w", err)
}
}
statementTimeoutParam := customParams["x-statement-timeout"]
statementTimeout := 0
if statementTimeoutParam != "" {
statementTimeout, err = strconv.Atoi(statementTimeoutParam)
if err != nil {
return nil, fmt.Errorf("could not parse x-statement-timeout as float: %w", err)
}
}
db, err := sql.Open("mysql", config.FormatDSN())
if err != nil {
return nil, err
}
mx, err := WithInstance(db, &Config{View on GitHub (pinned to 01a9643f14)
Solutions
- Change the x-no-lock value to a strconv.ParseBool-compatible literal: true, false, 1, or 0
- Remove the x-no-lock parameter entirely if you want the default locking behavior (enabled)
- Normalize the value before building the URL if it comes from a config file or environment variable
Example fix
// before url := "mysql://user:pass@tcp(db:3306)/app?x-no-lock=yes" // after url := "mysql://user:pass@tcp(db:3306)/app?x-no-lock=true"
Defensive patterns
Strategy: validation
Validate before calling
if v := params.Get("x-no-lock"); v != "" {
if _, err := strconv.ParseBool(v); err != nil {
return fmt.Errorf("x-no-lock must be a Go bool (true/false/1/0), got %q", v)
}
} Try / catch
drv, err := mysql.Open(dsn)
if err != nil && strings.Contains(err.Error(), "could not parse x-no-lock as bool") {
return fmt.Errorf("fix x-no-lock in DSN to true/false/1/0: %w", err)
} Prevention
- Only use strconv.ParseBool-accepted values: true/false/1/0 (not yes/no/on/off)
- Normalize config values with a helper before interpolating into the DSN
- Add a unit test that builds the DSN from your config
When it happens
Trigger: Calling Open (or database.Open with a mysql:// URL) whose query string contains x-no-lock set to a value that is not a valid Go boolean, e.g. x-no-lock=yes, x-no-lock=on, or x-no-lock=1.0 (database/mysql/mysql.go:241-246).
Common situations: Developers assume YAML-style truthy values (yes/no/on/off) work; templating or CLI flags pass strings like 'enabled'; a copy-pasted Postgres driver param name collides with different conventions; quoting in the URL leaves stray characters.
Related errors
- could not parse x-statement-timeout as float: %w
- to use TLS client authentication, both x-tls-cert and x-tls-
- no database name
- unable to parse option x-migrations-table-quoted: %w
- x-migrations-table must be quoted (for instance '"migrate"."
AI-assisted analysis of golang-migrate/migrate@01a9643f14 (2026-09-02).
Data as JSON: /api/errors/e7705436ab87ca70.
Report an issue: GitHub.