{"record":{"id":"8d83bad05bb8fc89","repo":"jmoiron/sqlx","slug":"number-of-bindvars-exceeds-arguments","errorCode":null,"errorMessage":"number of bindVars exceeds arguments","messagePattern":"number of bindVars exceeds arguments","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"bind.go","lineNumber":207,"sourceCode":"\t// some errors that we might have caught below will not be returned.\n\tif !anySlices {\n\t\treturn query, args, nil\n\t}\n\n\tnewArgs := make([]interface{}, 0, flatArgsCount)\n\n\tvar buf strings.Builder\n\tbuf.Grow(len(query) + len(\", ?\")*flatArgsCount)\n\n\tvar arg, offset int\n\n\tfor i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') {\n\t\tif arg >= len(meta) {\n\t\t\t// if an argument wasn't passed, lets return an error;  this is\n\t\t\t// not actually how database/sql Exec/Query works, but since we are\n\t\t\t// creating an argument list programmatically, we want to be able\n\t\t\t// to catch these programmer errors earlier.\n\t\t\treturn \"\", nil, errors.New(\"number of bindVars exceeds arguments\")\n\t\t}\n\n\t\targMeta := meta[arg]\n\t\targ++\n\n\t\t// not a slice, continue.\n\t\t// our questionmark will either be written before the next expansion\n\t\t// of a slice or after the loop when writing the rest of the query\n\t\tif argMeta.length == 0 {\n\t\t\toffset = offset + i + 1\n\t\t\tnewArgs = append(newArgs, argMeta.i)\n\t\t\tcontinue\n\t\t}\n\n\t\t// write everything up to and including our ? character\n\t\tbuf.WriteString(query[:offset+i+1])\n\n\t\tfor si := 1; si < argMeta.length; si++ {","sourceCodeStart":189,"sourceCodeEnd":225,"githubUrl":"https://github.com/jmoiron/sqlx/blob/41dac167fdad5e3fd81d66cafba0951dc6823a30/bind.go#L189-L225","documentation":"sqlx.In() walks the query string looking for '?' bind vars and expands each one using the corresponding argument. If the query contains more '?' placeholders than arguments were passed, the excess placeholders cannot be filled and this programmer error is reported (unlike database/sql, sqlx catches this eagerly at bind time).","triggerScenarios":"Calling sqlx.In/QueryInx with a query string containing more '?' characters than variadic arguments, e.g. sqlx.In(\"SELECT * FROM t WHERE a=? AND b=?\", valA) — the second '?' finds arg >= len(meta).","commonSituations":"Hand-edited queries where a condition was removed from the code but not the SQL string; typos producing stray '?' characters (including inside string literals); merging query fragments incorrectly.","solutions":["Count '?' placeholders in the query and make sure each has exactly one argument","Remove the extra '?' or add the missing argument","Prefer named parameters via NamedQuery/PrepareNamed to avoid positional mismatches","Note '?' inside quoted string literals are still counted — escape or remove them"],"exampleFix":"// before\nquery, args, err := sqlx.In(\"SELECT * FROM users WHERE id IN (?) AND status=?\", ids)\n// after\nquery, args, err := sqlx.In(\"SELECT * FROM users WHERE id IN (?) AND status=?\", ids, status)","handlingStrategy":"validation","validationCode":"if strings.Count(query, \"?\") != len(args) {\n    return \"\", nil, fmt.Errorf(\"query has %d placeholders but %d args\", strings.Count(query, \"?\"), len(args))\n}\nq, a, err := sqlx.In(query, args...)","typeGuard":null,"tryCatchPattern":"query, args, err := sqlx.In(q, args...)\nif err != nil {\n    if strings.Contains(err.Error(), \"number of bindVars exceeds arguments\") {\n        log.Printf(\"placeholder/arg mismatch in query: %s\", q)\n    }\n    return err\n}","preventionTips":["Count '?' in the query string and match against args before calling In","Keep query text and argument construction adjacent in code","Add unit tests that exercise every query-building path","Remember '?' inside string literals still counts as a placeholder"],"tags":["go","sqlx","query-building","bind-variables"],"backgroundTag":"bind-var-count-mismatch","analyzedSha":"41dac167fdad5e3fd81d66cafba0951dc6823a30","analyzedAt":"2026-09-03T06:10:20.382Z","contentChangedAt":"2026-09-03T06:10:20.382Z","schemaVersion":2},"datasetVersion":"2026-09-10T12:17:11.382Z"}