jackc/pgx · error

composite text format must start with '('

Error message

composite text format must start with '('

What it means

Returned by NewCompositeTextScanner when the textual composite value does not begin with '('. PostgreSQL's composite text output is always parenthesized, so a different first byte means the data is not a composite literal.

Solutions

  1. Supply composite text in PostgreSQL's '(field1,field2)' format
  2. Cast or re-type the source column to the composite type
Defensive patterns

Strategy: validation

When it happens

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

Appendix: source

Thrown at pgtype/composite.go:376

}

type CompositeTextScanner struct {
	m   *Map
	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

View on GitHub (pinned to ec1a0befd2)