jackc/pgx · error
invalid length for Close.ObjectType
Error message
invalid length for Close.ObjectType
What it means
Returned by Close.UnmarshalJSON when the JSON `ObjectType` field is not exactly one character long. In the wire protocol ObjectType is a single byte ('S' for prepared statement, 'P' for portal), so the JSON representation requires a single-character string. Anything else (empty string, a multi-char word like "statement", or a number) is rejected.
Source
Thrown at pgproto3/close.go:75
}
// UnmarshalJSON implements encoding/json.Unmarshaler.
func (dst *Close) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" {
return nil
}
var msg struct {
ObjectType string
Name string
}
if err := json.Unmarshal(data, &msg); err != nil {
return err
}
if len(msg.ObjectType) != 1 {
return errors.New("invalid length for Close.ObjectType")
}
dst.ObjectType = msg.ObjectType[0]
dst.Name = msg.Name
return nil
}
View on GitHub (pinned to ec1a0befd2)
Solutions
- Use the single-character wire form: "S" for prepared statement, "P" for portal.
- If your JSON source uses full words, map them before unmarshalling: `"statement" -> "S"`, `"portal" -> "P"`.
- Validate the JSON shape with a schema or a pre-unmarshal check that `len(objType) == 1` and report a clearer error to the caller.
- Regenerate any recorded fixtures with the library's own MarshalJSON so the field shape always matches.
Example fix
// before
raw := []byte(`{"ObjectType":"statement","Name":"foo"}`)
err := json.Unmarshal(raw, &closeMsg) // error
// after
raw := []byte(`{"ObjectType":"S","Name":"foo"}`)
err := json.Unmarshal(raw, &closeMsg) Defensive patterns
Strategy: validation
Validate before calling
func validateCloseJSON(raw []byte) error {
var probe struct{ ObjectType string }
if err := json.Unmarshal(raw, &probe); err != nil { return err }
if len(probe.ObjectType) != 1 {
return fmt.Errorf("ObjectType must be a single char (\"S\" or \"P\"), got %q", probe.ObjectType)
}
return nil
} Type guard
func isValidCloseObjectType(s string) bool {
return len(s) == 1 && (s == "S" || s == "P")
} Try / catch
var c pgproto3.Close
if err := json.Unmarshal(raw, &c); err != nil {
// log err mentioning ObjectType must be "S" or "P"
return err
} Prevention
- Always emit ObjectType as the single wire character: "S" (statement) or "P" (portal).
- Generate fixtures from MarshalJSON so the field shape is always correct.
- Add a JSON-schema check for one-char ObjectType when ingesting third-party JSON.
When it happens
Trigger: Calling `json.Unmarshal(data, &closeMsg)` on JSON where the `ObjectType` field has length != 1 — e.g. `{"ObjectType": "statement"}` or `{"ObjectType": ""}`.
Common situations: Test fixtures or recording/replay tools produce JSON with a human-readable ObjectType ("statement"/"portal") instead of the single-letter wire form. Also seen when a JSON generator omits ObjectType or encodes it as a numeric code.
Related errors
- invalid length for CopyBothResponse.OverallFormat
- invalid length for CopyInResponse.OverallFormat
- invalid length for CopyOutResponse.OverallFormat
- invalid length for Describe.ObjectType
- bad auth type
AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04).
Data as JSON: /data/errors/d15f48b1df1f948d.json.
Report an issue: GitHub.