jackc/pgx · error

invalid length for CopyInResponse.OverallFormat

Error message

invalid length for CopyInResponse.OverallFormat

What it means

Returned by CopyInResponse.UnmarshalJSON when the JSON `OverallFormat` field is not exactly one character. OverallFormat is a single wire byte (0 = text, 1 = binary), so the JSON form must be a one-char string. Words like "text" or numeric literals fail.

Source

Thrown at pgproto3/copy_in_response.go:90

}

// UnmarshalJSON implements encoding/json.Unmarshaler.
func (dst *CopyInResponse) UnmarshalJSON(data []byte) error {
	// Ignore null, like in the main JSON package.
	if string(data) == "null" {
		return nil
	}

	var msg struct {
		OverallFormat     string
		ColumnFormatCodes []uint16
	}
	if err := json.Unmarshal(data, &msg); err != nil {
		return err
	}

	if len(msg.OverallFormat) != 1 {
		return errors.New("invalid length for CopyInResponse.OverallFormat")
	}

	dst.OverallFormat = msg.OverallFormat[0]
	dst.ColumnFormatCodes = msg.ColumnFormatCodes
	return nil
}

View on GitHub (pinned to ec1a0befd2)

Solutions

  1. Use the single-char wire form: "0" (text) or "1" (binary).
  2. Map words to codes before unmarshalling: `"text" -> "0"`, `"binary" -> "1"`.
  3. Regenerate fixtures with MarshalJSON so the shape always matches.
  4. Pre-validate with a schema requiring a one-char OverallFormat string.

Example fix

// before
raw := []byte(`{"OverallFormat":"binary","ColumnFormatCodes":[1]}`)
err := json.Unmarshal(raw, &ci) // error

// after
raw := []byte(`{"OverallFormat":"1","ColumnFormatCodes":[1]}`)
err := json.Unmarshal(raw, &ci)
Defensive patterns

Strategy: validation

Validate before calling

func validateCopyInOverallFormat(raw []byte) error {
	var probe struct{ OverallFormat string }
	if err := json.Unmarshal(raw, &probe); err != nil { return err }
	if len(probe.OverallFormat) != 1 {
		return fmt.Errorf("OverallFormat must be one char (\"0\"/\"1\"), got %q", probe.OverallFormat)
	}
	return nil
}

Type guard

func isValidCopyOverallFormat(s string) bool {
	return len(s) == 1 && (s == "0" || s == "1")
}

Try / catch

var ci pgproto3.CopyInResponse
if err := json.Unmarshal(raw, &ci); err != nil {
    // clarify OverallFormat must be "0"/"1"
    return err
}

Prevention

When it happens

Trigger: `json.Unmarshal(data, &copyIn)` where `OverallFormat` has length != 1 — e.g. `{"OverallFormat": "binary"}` or `{"OverallFormat": 1}`.

Common situations: Replay fixtures, snapshot tests, or proxy tooling serialise OverallFormat as a word or number rather than the one-char string. Hand-edited JSON where the field is omitted (empty string) also triggers it.

Related errors


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