t8y2/dbx · error
custom type %s.%s is not fully defined
Error message
custom type %s.%s is not fully defined
What it means
The type row was found and scanned, but its typisdefined flag is false — the catalog entry for this type is a placeholder that is not fully defined, so the library refuses to produce details or DDL for it. PostgreSQL/Vastbase create such shells during partial type creation states; a fully usable custom type always has typisdefined = true.
Source
Thrown at agents/drivers/vastbase-go/vastbase_metadata.go:635
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("failed to read type %s.%s: %w", schema, name, err)
}
return nil, fmt.Errorf("custom type %s.%s does not exist", schema, name)
}
var oid, typbasetype, typrelid, typelem, typcollation int64
var typtype, typalign, typstorage string
var typisdefined, typnotnull, typbyval bool
var typdefaultbin, typdefault, inputFn, outputFn, receiveFn, sendFn, analyzeFn, comment, collname, relkind sql.NullString
var typlen sql.NullInt64
var typtypmod int64
if 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 {
return nil, fmt.Errorf("failed to read type %s.%s: %w", schema, name, err)
}
if err := rows.Close(); err != nil {
return nil, err
}
if !typisdefined {
return nil, fmt.Errorf("custom type %s.%s is not fully defined", schema, name)
}
if typelem != 0 {
return nil, fmt.Errorf("custom type %s.%s is an array companion type", schema, name)
}
kind, ok := customTypeKindFromCode(typtype)
if !ok {
return nil, fmt.Errorf("custom type %s.%s is a pseudo type (typtype=%s)", schema, name, typtype)
}
if relkind.Valid && relkind.String != "" && relkind.String != "c" {
return nil, fmt.Errorf("%s.%s is the auto-generated row type of a relation, not an independent custom type", schema, name)
}
properties := customTypeCommonProperties(inputFn, outputFn, receiveFn, sendFn, analyzeFn, typlen, typbyval, typalign, typstorage)
properties.DomainConstraints = []customTypeDomainConstraint{}
details := &customTypeDetails{
Name: name,
Schema: schema,
Kind: kind,View on GitHub (pinned to c0390bff16)
Solutions
- Inspect the type: SELECT typname, typisdefined FROM pg_type WHERE oid='schema.name'::regclass-ish (use to_regtype); confirm typisdefined=false
- Complete the type definition by re-running the full CREATE TYPE (including I/O functions for base types)
- Drop the shell type (DROP TYPE IF EXISTS) and recreate it properly with its dependencies created first
- Reorder migrations so all referenced types are fully created before this lookup runs
Example fix
// before
-- migration only created a shell via function signature
details, err := srv.getTypeDetails("public", "widget") // not fully defined
// after
-- complete the type first
CREATE TYPE public.widget AS (id int, name text);
details, err := srv.getTypeDetails("public", "widget") Defensive patterns
Strategy: validation
Validate before calling
-- ensure defined before lookup SELECT typisdefined FROM pg_type t JOIN pg_namespace n ON n.oid=t.typnamespace WHERE n.nspname=$1 AND t.typname=$2;
Try / catch
if err != nil && strings.Contains(err.Error(), "not fully defined") { /* recreate the type */ } Prevention
- Run complete CREATE TYPE statements atomically
- Clean up shell types after failed migrations
When it happens
Trigger: Calling getTypeDetails on a type whose catalog row has typisdefined=false; typically seen on types left behind by an interrupted CREATE TYPE, shell types created implicitly by CREATE FUNCTION referencing a not-yet-created type, or corrupted/partial catalog state after a failed migration.
Common situations: A migration that created shell types then failed before CREATE TYPE completed; DDL generated by tools that forward-declare types; restoring a dump partially; manually created stub entries while scaffolding I/O functions.
Related errors
- custom type %s.%s does not exist
- custom type %s.%s is an array companion type
- custom type %s.%s is a pseudo type (typtype=%s)
- custom type %s.%s is a pseudo type (typtype=%s)
- %s.%s is the auto-generated row type of a relation, not an i
AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05).
Data as JSON: /api/errors/713d8a554ea14749.
Report an issue: GitHub.