{"id":"4a565ea5faa3275b","repo":"jackc/pgx","slug":"unknown-typtype","errorCode":null,"errorMessage":"unknown typtype","messagePattern":"unknown typtype","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"conn.go","lineNumber":1364,"sourceCode":"\t\tif !ok {\n\t\t\treturn nil, errors.New(\"range element OID not registered\")\n\t\t}\n\n\t\treturn &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.RangeCodec{ElementType: dt}}, nil\n\tcase \"m\": // multirange\n\t\telementOID, err := c.getMultiRangeElementOID(ctx, oid)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tdt, ok := c.TypeMap().TypeForOID(elementOID)\n\t\tif !ok {\n\t\t\treturn nil, errors.New(\"multirange element OID not registered\")\n\t\t}\n\n\t\treturn &pgtype.Type{Name: typeName, OID: oid, Codec: &pgtype.MultirangeCodec{ElementType: dt}}, nil\n\tdefault:\n\t\treturn &pgtype.Type{}, errors.New(\"unknown typtype\")\n\t}\n}\n\nfunc (c *Conn) getArrayElementOID(ctx context.Context, oid uint32) (uint32, error) {\n\tvar typelem uint32\n\n\terr := c.QueryRow(ctx, \"select typelem from pg_type where oid=$1\", oid).Scan(&typelem)\n\tif err != nil {\n\t\treturn 0, err\n\t}\n\n\treturn typelem, nil\n}\n\nfunc (c *Conn) getRangeElementOID(ctx context.Context, oid uint32) (uint32, error) {\n\tvar typelem uint32\n\n\terr := c.QueryRow(ctx, \"select rngsubtype from pg_range where rngtypid=$1\", oid).Scan(&typelem)","sourceCodeStart":1346,"sourceCodeEnd":1382,"githubUrl":"https://github.com/jackc/pgx/blob/ec1a0befd22592cffffdeeb0a50311b506372f4c/conn.go#L1346-L1382","documentation":"Returned by Conn.LoadType when pg_type.typtype of the requested type is not one of b/c/d/e/r/m (base/composite/domain/enum/range/multirange). The switch falls through to default at conn.go:1364. This usually means the type is a pseudo-type (typtype='p', e.g. void, anyelement, trigger, record), a table row type, or a typtype introduced by a newer PostgreSQL version pgx does not yet handle.","triggerScenarios":"Calling Conn.LoadType on a pseudo-type (e.g. 'record', 'anyelement', 'trigger', 'void'), a table's implicit row type, or a brand-new kind of type added by a future/extension PostgreSQL version.","commonSituations":"Trying to LoadType a table name (row types are 'c' composites only for CREATE TYPE AS composites; tables expose row types that LoadType does not model); pointing LoadType at 'anyelement'/generic types; an extension introducing a novel typtype.","solutions":["Do not call LoadType on pseudo-types or table row types; they are not derivable types pgx models.","For a table-like payload, define a CREATE TYPE … AS (…) composite and LoadType that name.","Upgrade pgx — newer versions may handle additional typtypes.","Check SELECT typtype FROM pg_type WHERE typname=… to confirm the kind before calling LoadType."],"exampleFix":"// before\nt, err := conn.LoadType(ctx, \"trigger\") // typtype='p' -> unknown typtype\n\n// after\nvar tt string\nconn.QueryRow(ctx, \"select typtype::text from pg_type where typname=$1\", name).Scan(&tt)\nif tt != \"b\" && tt != \"c\" && tt != \"d\" && tt != \"e\" && tt != \"r\" && tt != \"m\" {\n    return nil, fmt.Errorf(\"type %s is %q, not LoadType-able\", name, tt)\n}","handlingStrategy":"validation","validationCode":"var tt string\nif err := conn.QueryRow(ctx, \"select typtype::text from pg_type where typname=$1\", name).Scan(&tt); err != nil { return err }\nswitch tt {\ncase \"b\",\"c\",\"d\",\"e\",\"r\",\"m\":\n    // LoadType-able\ndefault:\n    return fmt.Errorf(\"type %s has typtype %q; pgx cannot LoadType it\", name, tt)\n}\nreturn nil","typeGuard":"func loadTypeable(tt string) bool {\n    switch tt {\n    case \"b\",\"c\",\"d\",\"e\",\"r\",\"m\": return true\n    }\n    return false\n}","tryCatchPattern":"if t, err := conn.LoadType(ctx, name); err != nil {\n    if strings.Contains(err.Error(), \"unknown typtype\") {\n        // not a LoadType-able type; skip\n        return nil, nil\n    }\n    return nil, err\n}","preventionTips":["Check typtype via pg_type before calling LoadType.","Do not LoadType pseudo-types or table row types.","Upgrade pgx to gain support for newer typtypes."],"tags":["types","loadtype","unsupported","pseudo-type"],"analyzedSha":"ec1a0befd22592cffffdeeb0a50311b506372f4c","analyzedAt":"2026-08-04T22:52:11.263Z","schemaVersion":2}