jackc/pgx · error
range element OID not registered
Error message
range element OID not registered
What it means
Returned by Conn.LoadType for a typtype='r' (range) type when the range's element OID (looked up via pg_range) is not in the connection's TypeMap (conn.go:1345-1347). Range codecs wrap an element codec; if the element is unknown, the range cannot be decoded/encoded.
Source
Thrown at conn.go:1347
return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.CompositeCodec{Fields: fields}}, nil
case "d": // domain
dt, ok := c.TypeMap().TypeForOID(typbasetype)
if !ok {
return nil, errors.New("domain base type OID not registered")
}
return &pgtype.Type{Name: typeName, OID: oid, Codec: dt.Codec}, nil
case "e": // enum
return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.EnumCodec{}}, nil
case "r": // range
elementOID, err := c.getRangeElementOID(ctx, oid)
if err != nil {
return nil, err
}
dt, ok := c.TypeMap().TypeForOID(elementOID)
if !ok {
return nil, errors.New("range element OID not registered")
}
return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.RangeCodec{ElementType: dt}}, nil
case "m": // multirange
elementOID, err := c.getMultiRangeElementOID(ctx, oid)
if err != nil {
return nil, err
}
dt, ok := c.TypeMap().TypeForOID(elementOID)
if !ok {
return nil, errors.New("multirange element OID not registered")
}
return &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.MultirangeCodec{ElementType: dt}}, nil
default:
return &pgtype.Type{}, errors.New("unknown typtype")
}View on GitHub (pinned to ec1a0befd2)
Solutions
- LoadType and register the range's element type first, then LoadType the range.
- Inspect pg_range.rngsubtype to discover the element OID and ensure it is registered.
- Register the element codec manually if it is non-standard.
- Order LoadType calls: scalar element → range → (optionally) multirange.
Example fix
// before
rt, err := conn.LoadType(ctx, "myrange") // subtype 'mytype' unknown
// -> "range element OID not registered"
// after
elem, err := conn.LoadType(ctx, "mytype")
if err != nil { return err }
conn.TypeMap().RegisterType(elem)
rt, err := conn.LoadType(ctx, "myrange") Defensive patterns
Strategy: validation
Validate before calling
// look up pg_range.rngsubtype, register it, then load the range
var elemOID uint32
conn.QueryRow(ctx, "select rngsubtype from pg_range where rngtypid=$1::regtype::oid", rangeName).Scan(&elemOID)
if _, ok := conn.TypeMap().TypeForOID(elemOID); !ok {
// LoadType element, register, then LoadType range
} Type guard
func rangeElementRegistered(m *pgtype.Map, elemOID uint32) bool { _, ok := m.TypeForOID(elemOID); return ok } Try / catch
if t, err := conn.LoadType(ctx, rangeName); err != nil {
if strings.Contains(err.Error(), "range element OID not registered") {
// load+register element, retry
}
return nil, err
} Prevention
- LoadType element types before range types.
- Order registration: element → range → multirange.
- Register custom element codecs explicitly.
When it happens
Trigger: Calling Conn.LoadType on a custom range (e.g. CREATE TYPE myrange AS RANGE (subtype=mytype)) before the subtype 'mytype' is loaded and registered.
Common situations: Custom range subtypes defined over user types; loading range types before their element types; migrations adding ranges over newly-created base types.
Related errors
- array element OID not registered
- domain base type OID not registered
- multirange element OID not registered
- unknown typtype
AI-assisted analysis of jackc/pgx@ec1a0befd2 (2026-08-04).
Data as JSON: /data/errors/6b557b0dcf17a4cc.json.
Report an issue: GitHub.