jackc/pgx · error

got values, but dst struct has only fields

Error message

got %d values, but dst struct has only %d fields

What it means

RowToAddrOfStructByPos requires T's number of scannable struct fields (public, not tagged db:"-") to equal the row's column count; the query returned more columns than the struct has fields, so positional matching cannot proceed.

Solutions

  1. Add or export struct fields so every selected column has one
  2. Narrow the SELECT list to the fields the struct defines
  3. Prefer RowToStructByName/Lax when columns and fields only partially overlap
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at rows.go:589 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04). Data as JSON: /api/errors/17d0a78bfe3e0a1a. Report an issue: GitHub.

Appendix: source

Thrown at rows.go:589

// RowToAddrOfStructByPos returns the address of a T scanned from row. T must be a struct. T must have the same number a
// public fields as row has fields. The row and T fields will be matched by position. If the "db" struct tag is "-" then
// the field will be ignored.
func RowToAddrOfStructByPos[T any](row CollectableRow) (*T, error) {
	var value T
	err := (&positionalStructRowScanner{ptrToStruct: &value}).ScanRow(row)
	return &value, err
}

type positionalStructRowScanner struct {
	ptrToStruct any
}

func (rs *positionalStructRowScanner) ScanRow(rows CollectableRow) error {
	typ := reflect.TypeOf(rs.ptrToStruct).Elem()
	fields := lookupStructFields(typ)
	if len(rows.RawValues()) > len(fields) {
		return fmt.Errorf(
			"got %d values, but dst struct has only %d fields",
			len(rows.RawValues()),
			len(fields),
		)
	}
	scanTargets := setupStructScanTargets(rs.ptrToStruct, fields)
	return rows.Scan(scanTargets...)
}

// Map from reflect.Type -> []structRowField
var positionalStructFieldMap sync.Map

func lookupStructFields(t reflect.Type) []structRowField {
	if cached, ok := positionalStructFieldMap.Load(t); ok {
		return cached.([]structRowField)
	}

	fieldStack := make([]int, 0, 1)

View on GitHub (pinned to ec1a0befd2)