go-sql-driver/mysql · error
mysql: driver does not support the use of Named Parameters
Error message
mysql: driver does not support the use of Named Parameters
What it means
Thrown by namedValueToValue (utils.go:785) when any element of the parameter slice has a non-empty Name — i.e. the caller passed sql.Named(...) / named parameters. The go-sql-driver explicitly does not implement named parameters (tracked as issue #561); database/sql normally strips names before calling the driver, so reaching this branch means named args leaked through to the driver level.
Source
Thrown at utils.go:785
func (ae *atomicError) Set(value error) {
ae.value.Store(value)
}
// Value returns the current error value
func (ae *atomicError) Value() error {
if v := ae.value.Load(); v != nil {
// this will panic if the value doesn't implement the error interface
return v.(error)
}
return nil
}
func namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {
dargs := make([]driver.Value, len(named))
for n, param := range named {
if len(param.Name) > 0 {
// TODO: support the use of Named Parameters #561
return nil, errors.New("mysql: driver does not support the use of Named Parameters")
}
dargs[n] = param.Value
}
return dargs, nil
}
func mapIsolationLevel(level driver.IsolationLevel) (string, error) {
switch sql.IsolationLevel(level) {
case sql.LevelRepeatableRead:
return "REPEATABLE READ", nil
case sql.LevelReadCommitted:
return "READ COMMITTED", nil
case sql.LevelReadUncommitted:
return "READ UNCOMMITTED", nil
case sql.LevelSerializable:
return "SERIALIZABLE", nil
default:
return "", fmt.Errorf("mysql: unsupported isolation level: %v", level)View on GitHub (pinned to c426bd9379)
Solutions
- Replace sql.Named("x", v) with a positional '?' placeholder and pass v positionally.
- If you have a map of named params, convert them to positional '?' in the same order you pass the values.
- Switch to a query builder that emits positional placeholders for MySQL, or pre-process the SQL to substitute names.
- Do not rely on @name/:name support — this driver documents it as unsupported.
Example fix
// before
db.Exec("INSERT INTO t(a,b) VALUES(:a,:b)", sql.Named("a", 1), sql.Named("b", 2))
// after
db.Exec("INSERT INTO t(a,b) VALUES(?,?)", 1, 2) Defensive patterns
Strategy: validation
Validate before calling
// reject named params before they reach the driver
func positionalArgs(query string, args []any) (string, []any, error) {
var out []any
for _, a := range args {
if nv, ok := a.(driver.NamedValue); ok && nv.Name != "" {
return "", nil, errors.New("named parameters not supported by mysql driver")
}
if named, ok := a.(sql.NamedArg); ok {
return "", nil, fmt.Errorf("named parameter %q not supported", named.Name)
}
out = append(out, a)
}
return query, out, nil
} Type guard
// hasNamedArg detects sql.NamedArg / named values before exec
func hasNamedArg(args []any) bool {
for _, a := range args {
if _, ok := a.(sql.NamedArg); ok {
return true
}
}
return false
} Prevention
- Always use '?' positional placeholders with this driver.
- Lint for sql.Named usage in code paths that target MySQL.
- Review ORM/query-builder config to ensure positional placeholder emission.
When it happens
Trigger: Calling db.Exec/Query with an argument built by sql.Named("col", val) or a struct expansion that yields named args, in a code path where database/sql did not (or could not) map names to positional placeholders. The driver rejects the first named arg it sees.
Common situations: Using a query builder / ORM that emits @name or :name parameters with this driver; passing sql.Named directly; upgrading from a driver that supported named params to this one; using a high-level helper that always names its args.
Related errors
- mysql: unsupported isolation level: %v
- reader '%s' is <nil>
- reader '%s' is not registered
- argument count mismatch (got: %d; has: %d)
- cannot convert type: %T
AI-assisted analysis of go-sql-driver/mysql@c426bd9379 (2026-08-04).
Data as JSON: /data/errors/51243cad227a1492.json.
Report an issue: GitHub.