{"record":{"id":"179b36e23f4edf5e","repo":"t8y2/dbx","slug":"custom-type-s-s-is-an-array-companion-type-179b36","errorCode":null,"errorMessage":"custom type %s.%s is an array companion type","messagePattern":"custom type (.+?)\\.(.+?) is an array companion type","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"agents/drivers/vastbase-go/vastbase_metadata.go","lineNumber":638,"sourceCode":"\t\treturn nil, fmt.Errorf(\"custom type %s.%s does not exist\", schema, name)\n\t}\n\tvar oid, typbasetype, typrelid, typelem, typcollation int64\n\tvar typtype, typalign, typstorage string\n\tvar typisdefined, typnotnull, typbyval bool\n\tvar typdefaultbin, typdefault, inputFn, outputFn, receiveFn, sendFn, analyzeFn, comment, collname, relkind sql.NullString\n\tvar typlen sql.NullInt64\n\tvar typtypmod int64\n\tif err := rows.Scan(&oid, &typtype, &typisdefined, &typbasetype, &typnotnull, &typrelid, &typelem, &typcollation, &typdefaultbin, &typdefault, &typlen, &typbyval, &typalign, &typstorage, &typtypmod, &inputFn, &outputFn, &receiveFn, &sendFn, &analyzeFn, &comment, &relkind, &collname); err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to read type %s.%s: %w\", schema, name, err)\n\t}\n\tif err := rows.Close(); err != nil {\n\t\treturn nil, err\n\t}\n\tif !typisdefined {\n\t\treturn nil, fmt.Errorf(\"custom type %s.%s is not fully defined\", schema, name)\n\t}\n\tif typelem != 0 {\n\t\treturn nil, fmt.Errorf(\"custom type %s.%s is an array companion type\", schema, name)\n\t}\n\tkind, ok := customTypeKindFromCode(typtype)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"custom type %s.%s is a pseudo type (typtype=%s)\", schema, name, typtype)\n\t}\n\tif relkind.Valid && relkind.String != \"\" && relkind.String != \"c\" {\n\t\treturn nil, fmt.Errorf(\"%s.%s is the auto-generated row type of a relation, not an independent custom type\", schema, name)\n\t}\n\n\tproperties := customTypeCommonProperties(inputFn, outputFn, receiveFn, sendFn, analyzeFn, typlen, typbyval, typalign, typstorage)\n\tproperties.DomainConstraints = []customTypeDomainConstraint{}\n\tdetails := &customTypeDetails{\n\t\tName:       name,\n\t\tSchema:     schema,\n\t\tKind:       kind,\n\t\tComment:    nullStringPtr(comment),\n\t\tMembers:    []customTypeMember{},\n\t\tProperties: properties,","sourceCodeStart":620,"sourceCodeEnd":656,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/vastbase-go/vastbase_metadata.go#L620-L656","documentation":"The catalog row has typelem != 0, which identifies the type as the implicit array companion (_name) that PostgreSQL/Vastbase auto-creates for every base type, not a user-facing independent custom type. The library rejects it because describing an auto-generated array shell as a 'custom type' would be misleading; array handling belongs to column/array metadata instead.","triggerScenarios":"Passing the internal array type name (e.g. '_widget', '_int4') or resolving a name that maps to the array companion OID rather than the element type; looking up a type obtained from typarray/typreceive contexts; introspection code that enumerated pg_type without filtering typelem != 0.","commonSituations":"Scripts that scrape pg_type without excluding array shells; hand-written migrations or ORM dumps that reference internal _-prefixed names; tooling that resolved an array column's type OID and then asked for its 'custom type' details.","solutions":["Use the element type name instead of the array companion: query elem type via SELECT e.typname FROM pg_type t JOIN pg_type e ON e.oid=t.typelem WHERE t.typname='<arrayname>'","Strip the leading underscore and/or resolve the base type before calling getTypeDetails","Filter introspection queries with typelem = 0 (and typtype in ('e','c','d','r','m','b')) when enumerating candidate custom types","If you actually need array info, use column/array metadata APIs rather than custom-type details"],"exampleFix":"// before\nsrv.getTypeDetails(\"public\", \"_widget\")   // array companion\n// after\nsrv.getTypeDetails(\"public\", \"widget\")    // the element type","handlingStrategy":"type-guard","validationCode":"if strings.HasPrefix(name, \"_\") { name = strings.TrimPrefix(name, \"_\") }","typeGuard":"func isArrayCompanionName(n string) bool { return strings.HasPrefix(n, \"_\") }","tryCatchPattern":"if err != nil && strings.Contains(err.Error(), \"array companion\") { name = strings.TrimPrefix(name, \"_\"); details, err = srv.getTypeDetails(schema, name) }","preventionTips":["Filter typelem != 0 rows out of custom-type listings","Prefer column metadata for array handling"],"tags":["postgres","metadata","array-type","catalog"],"backgroundTag":"array-companion-type","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}