go-sql-driver/mysql · error

argument count mismatch

Error message

argument count mismatch (got: %d; has: %d)

What it means

writeExecutePacket compares the number of supplied arguments against the prepared statement's parameter count (stmt.paramCount, returned by the server when the statement was prepared). A mismatch means the number of '?' placeholders differs from the arguments passed to Exec.

Solutions

  1. Align the number of Exec/Query arguments with the number of '?' placeholders in the SQL.
  2. Use a helper that counts placeholders and asserts against len(args) before Exec.
  3. When SQL changes, update the call site in the same commit.

Example fix

// before
stmt.Exec(42, "extra") // SQL: INSERT INTO t(id) VALUES (?)
// after
stmt.Exec(42)
Defensive patterns

Strategy: validation

Validate before calling

// Count placeholders and assert against args before executing.
import "strings"
ph := strings.Count(query, "?")
if ph != len(args) {
    return fmt.Errorf("expected %d args, got %d", ph, len(args))
}

Type guard

null

Try / catch

// The mismatch is returned from Exec/Query; treat as a programmer error.
if _, err := stmt.Exec(args...); err != nil {
    return err
}

Prevention

When it happens

Trigger: Calling stmt.Exec with the wrong number of args, e.g. stmt.Exec(1,2) for "INSERT INTO t VALUES (?)", or passing fewer args than placeholders.

Common situations: Refactoring SQL changes the placeholder count but the Exec call is not updated; dynamic query construction; off-by-one in argument slicing.

Related errors


AI-assisted analysis of go-sql-driver/mysql@03d76c7e07 (2026-08-07). Data as JSON: /api/errors/5ac1e77291b4bb58. Report an issue: GitHub.

Appendix: source

Thrown at packets.go:1047

		// Send CMD packet
		err := stmt.mc.writePacket(data[:4+pktLen])
		// Every COM_LONG_DATA packet reset Packet Sequence
		stmt.mc.resetSequence()
		if err == nil {
			data = data[pktLen-dataOffset:]
			continue
		}
		return err
	}

	return nil
}

// Execute Prepared Statement
// https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_com_stmt_execute.html
func (stmt *mysqlStmt) writeExecutePacket(args []driver.Value) error {
	if len(args) != stmt.paramCount {
		return fmt.Errorf(
			"argument count mismatch (got: %d; has: %d)",
			len(args),
			stmt.paramCount,
		)
	}

	const minPktLen = 4 + 1 + 4 + 1 + 4
	mc := stmt.mc

	// Determine threshold dynamically to avoid packet size shortage.
	longDataSize := max(mc.maxAllowedPacket/(stmt.paramCount+1), 64)

	// Reset packet-sequence
	mc.resetSequence()

	var data []byte
	var err error

View on GitHub (pinned to 03d76c7e07)