{"id":"51243cad227a1492","repo":"go-sql-driver/mysql","slug":"mysql-driver-does-not-support-the-use-of-named-pa","errorCode":null,"errorMessage":"mysql: driver does not support the use of Named Parameters","messagePattern":"mysql: driver does not support the use of Named Parameters","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"utils.go","lineNumber":785,"sourceCode":"func (ae *atomicError) Set(value error) {\n\tae.value.Store(value)\n}\n\n// Value returns the current error value\nfunc (ae *atomicError) Value() error {\n\tif v := ae.value.Load(); v != nil {\n\t\t// this will panic if the value doesn't implement the error interface\n\t\treturn v.(error)\n\t}\n\treturn nil\n}\n\nfunc namedValueToValue(named []driver.NamedValue) ([]driver.Value, error) {\n\tdargs := make([]driver.Value, len(named))\n\tfor n, param := range named {\n\t\tif len(param.Name) > 0 {\n\t\t\t// TODO: support the use of Named Parameters #561\n\t\t\treturn nil, errors.New(\"mysql: driver does not support the use of Named Parameters\")\n\t\t}\n\t\tdargs[n] = param.Value\n\t}\n\treturn dargs, nil\n}\n\nfunc mapIsolationLevel(level driver.IsolationLevel) (string, error) {\n\tswitch sql.IsolationLevel(level) {\n\tcase sql.LevelRepeatableRead:\n\t\treturn \"REPEATABLE READ\", nil\n\tcase sql.LevelReadCommitted:\n\t\treturn \"READ COMMITTED\", nil\n\tcase sql.LevelReadUncommitted:\n\t\treturn \"READ UNCOMMITTED\", nil\n\tcase sql.LevelSerializable:\n\t\treturn \"SERIALIZABLE\", nil\n\tdefault:\n\t\treturn \"\", fmt.Errorf(\"mysql: unsupported isolation level: %v\", level)","sourceCodeStart":767,"sourceCodeEnd":803,"githubUrl":"https://github.com/go-sql-driver/mysql/blob/c426bd93799de0f0e094c8f0582872c529d0ed0a/utils.go#L767-L803","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\ndb.Exec(\"INSERT INTO t(a,b) VALUES(:a,:b)\", sql.Named(\"a\", 1), sql.Named(\"b\", 2))\n\n// after\ndb.Exec(\"INSERT INTO t(a,b) VALUES(?,?)\", 1, 2)","handlingStrategy":"validation","validationCode":"// reject named params before they reach the driver\nfunc positionalArgs(query string, args []any) (string, []any, error) {\n    var out []any\n    for _, a := range args {\n        if nv, ok := a.(driver.NamedValue); ok && nv.Name != \"\" {\n            return \"\", nil, errors.New(\"named parameters not supported by mysql driver\")\n        }\n        if named, ok := a.(sql.NamedArg); ok {\n            return \"\", nil, fmt.Errorf(\"named parameter %q not supported\", named.Name)\n        }\n        out = append(out, a)\n    }\n    return query, out, nil\n}","typeGuard":"// hasNamedArg detects sql.NamedArg / named values before exec\nfunc hasNamedArg(args []any) bool {\n    for _, a := range args {\n        if _, ok := a.(sql.NamedArg); ok {\n            return true\n        }\n    }\n    return false\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["query","parameters","named-params","api-misuse"],"analyzedSha":"c426bd93799de0f0e094c8f0582872c529d0ed0a","analyzedAt":"2026-08-04T21:52:59.219Z","schemaVersion":2}