t8y2/dbx · error

failed to read composite fields: %w

Error message

failed to read composite fields: %w

What it means

After getTypeDetails classifies a type as composite (typtype 'c'), it runs customTypeCompositeMembers, which executes the composite-fields catalog SQL (querying attribute columns of the type's underlying relation via typrelid) through metadataQuery. If that query fails, the error is wrapped as 'failed to read composite fields', meaning the field list of the composite type cannot be built.

Source

Thrown at agents/drivers/kingbase-go/kingbase_metadata.go:818

	index := 0
	for rows.Next() {
		var label string
		var sortOrder float64
		if err := rows.Scan(&label, &sortOrder); err != nil {
			return nil, err
		}
		// enumsortorder is float4; ALTER TYPE ... ADD VALUE BEFORE/AFTER can
		// yield fractional values. Use the ORDER BY position for a unique key.
		index++
		members = append(members, customTypeMember{Ordinal: int32(index), EnumValue: &label})
	}
	return members, rows.Err()
}

func (s *server) customTypeCompositeMembers(sqlTemplate string, typrelid int64) ([]customTypeMember, error) {
	rows, err := s.metadataQuery(fmt.Sprintf(sqlTemplate, typrelid, typrelid))
	if err != nil {
		return nil, fmt.Errorf("failed to read composite fields: %w", err)
	}
	defer rows.Close()
	var members []customTypeMember
	for rows.Next() {
		var member customTypeMember
		var hasDefault bool
		var comment sql.NullString
		if err := rows.Scan(&member.Name, &member.DataType, &member.Ordinal, &member.Nullable, &hasDefault, &member.Default, &comment); err != nil {
			return nil, err
		}
		if !hasDefault {
			member.Default = nil
		}
		member.Comment = nullStringPtr(comment)
		members = append(members, member)
	}
	return members, rows.Err()
}

View on GitHub (pinned to c0390bff16)

Solutions

  1. Inspect the wrapped inner error (%w) for the actual SQL failure
  2. Grant the connecting role SELECT on pg_attribute/sys_attribute, pg_class/sys_class, and pg_type/sys_type
  3. Ensure the driver's catalog-mode setting matches the server (postgresCatalog flag)
  4. Recreate the composite type if its underlying relation row is missing/stale in the catalog

Example fix

// before
rows, err := s.metadataQuery(fmt.Sprintf(sqlTemplate, typrelid, typrelid))
// after — surface typrelid for diagnosis
if err != nil { return nil, fmt.Errorf("failed to read composite fields (typrelid=%d): %w", typrelid, err) }
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure the role can read attribute/class catalogs and that the type's relation exists
if !roleCanSelect("pg_attribute", "pg_class") && !roleCanSelect("sys_attribute", "sys_class") { grantCompositeCatalogAccess() }
if !typeRelationExists(typrelid) { recreateCompositeType(name) }

Type guard

func isCompositeDetails(details *customTypeDetails) bool {
  return details != nil && details.Kind == "composite"
} // only composites go through the field-listing path

Try / catch

details, err := server.GetTypeDetails(schema, name)
if err != nil && strings.Contains(err.Error(), "failed to read composite fields") {
  if isTransient(err) { return retryWithBackoff() }
  return fmt.Errorf("composite fields unreadable for %s.%s: %w", schema, name, err)
}

Prevention

When it happens

Trigger: Calling the type details API on a composite type whose field catalog query (join of pg_attribute/sys_attribute with pg_class/sys_class on typrelid) fails — the typrelid template is interpolated twice, so a malformed template or a catalog-access failure surfaces here.

Common situations: Role lacking SELECT on attribute/class catalogs; dropped relation behind a composite type leaving stale typrelid; Kingbase mode mismatch (sys_catalog vs pg_catalog) producing invalid SQL; transient DB errors.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/ce694ad07e833e3b. Report an issue: GitHub.