jackc/pgx · error

composite text format must end with ')'

Error message

composite text format must end with ')'

What it means

NewCompositeTextScanner validates the outer shape of a text composite (record) value: it must be parenthesized, and the last byte must be ')'. This error fires when the closing parenthesis is missing, e.g. '(1,2' — the scanner refuses to start on a structurally incomplete record.

Solutions

  1. Fix the value so it is a well-formed parenthesized record literal
  2. Check for truncation when the composite string was produced or transported
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at pgtype/composite.go:380 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/d5d5fc2cb7b6bcb3. Report an issue: GitHub.

Appendix: source

Thrown at pgtype/composite.go:380

	rp  int
	src []byte

	fieldBytes []byte
	err        error
}

// NewCompositeTextScanner a scanner over a text encoded composite value.
func NewCompositeTextScanner(m *Map, src []byte) *CompositeTextScanner {
	if len(src) < 2 {
		return &CompositeTextScanner{err: fmt.Errorf("Record incomplete %v", src)}
	}

	if src[0] != '(' {
		return &CompositeTextScanner{err: fmt.Errorf("composite text format must start with '('")}
	}

	if src[len(src)-1] != ')' {
		return &CompositeTextScanner{err: fmt.Errorf("composite text format must end with ')'")}
	}

	return &CompositeTextScanner{
		m:   m,
		rp:  1,
		src: src,
	}
}

// Next advances the scanner to the next field. It returns false after the last field is read or an error occurs. After
// Next returns false, the Err method can be called to check if any errors occurred.
func (cfs *CompositeTextScanner) Next() bool {
	if cfs.err != nil {
		return false
	}

	if cfs.rp >= len(cfs.src) {
		return false

View on GitHub (pinned to ec1a0befd2)