bytebase/bytebase · error

unknown object kind %d

Error message

unknown object kind %d

What it means

wtInstallReal dispatches each collected object by its kind (table, view, sequence, index, constraint, composite type, ...). If obj.kind holds a value the switch does not handle, it returns `unknown object kind %d`. This is a defensive invariant check: the library throws it when the walkthrough loader collects an object kind that installation has no handler for.

Source

Thrown at backend/plugin/schema/pg/walk_through_loader.go:692

			return cat.AddConstraint(obj.schema, obj.parentName, catalog.ConstraintDef{
				Name:    obj.idxMeta.Name,
				Type:    catalog.ConstraintPK,
				Columns: wtUnquoteColumns(obj.idxMeta.Expressions),
			})
		}
		if obj.idxMeta.IsConstraint && obj.idxMeta.Unique {
			return cat.AddConstraint(obj.schema, obj.parentName, catalog.ConstraintDef{
				Name:    obj.idxMeta.Name,
				Type:    catalog.ConstraintUnique,
				Columns: wtUnquoteColumns(obj.idxMeta.Expressions),
			})
		}
		return wtInstallIndex(cat, obj)

	case kindWTConstraint:
		return wtInstallConstraint(cat, obj)
	}
	return errors.Errorf("unknown object kind %d", obj.kind)
}

func wtInstallSequence(cat *catalog.Catalog, obj *wtObjectEntry) error {
	seq := obj.seqMeta
	if seq == nil {
		return errors.New("sequence has no metadata")
	}

	stmt := &ast.CreateSeqStmt{
		Sequence: &ast.RangeVar{
			Schemaname:     obj.schema,
			Relname:        seq.Name,
			Relpersistence: 'p',
		},
	}

	var opts []ast.Node
	if seq.Increment != "" && seq.Increment != "0" {

View on GitHub (pinned to 1870550677)

Solutions

  1. Add a case for the new kind in wtInstallReal's switch delegating to a wtInstall* handler
  2. Check wtCollectObjects for code that constructs wtObjectEntry with an uninitialized or unhandled kind
  3. Log obj.name alongside the kind to identify which object triggers the gap

Example fix

// before
switch obj.kind {
case kindWTConstraint:
	return wtInstallConstraint(cat, obj)
}
return errors.Errorf("unknown object kind %d", obj.kind)
// after
switch obj.kind {
case kindWTConstraint:
	return wtInstallConstraint(cat, obj)
case kindWTFunction:
	return wtInstallFunction(cat, obj)
}
return errors.Errorf("unknown object kind %d", obj.kind)
Defensive patterns

Strategy: validation

Validate before calling

switch obj.kind {
case kindWTTable, kindWTView, kindWTSequence, kindWTIndex, kindWTConstraint, kindWTComposite:
default:
	return fmt.Errorf("object %s: unhandled kind %d", obj.name, obj.kind)
}

Type guard

func knownKind(k wtKind) bool {
	switch k {
	case kindWTTable, kindWTView, kindWTSequence, kindWTIndex, kindWTConstraint, kindWTComposite:
		return true
	}
	return false
}

Try / catch

if err := wtInstallReal(cat, obj); err != nil {
	if strings.Contains(err.Error(), "unknown object kind") {
		log.Warnf("unsupported object %s: %v", obj.name, err)
		return nil
	}
	return err
}

Prevention

When it happens

Trigger: A wtObjectEntry whose kind field was set to a value outside the kinds handled by the switch in wtInstallReal (e.g. a newly added kindWT* constant collected by wtCollectObjects but not given a wtInstall* branch).

Common situations: A developer added a new object kind to wtCollectObjects but forgot to add the corresponding case in wtInstallReal; corrupted/inconsistent in-memory object entries built during collection.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of bytebase/bytebase@1870550677 (2026-09-06). Data as JSON: /api/errors/3628bae0a4c23689. Report an issue: GitHub.