gastownhall/beads · error

ErrValidation

ErrValidation

Error message

%w: apply batch item %d has unknown kind %q

What it means

A validation error from the unit-of-work batch applier: a batch item carried a Kind the applier does not recognize. Only create, update, close, and dep-add items are supported; anything else fails the whole apply with publicops.ErrValidation.

Source

Thrown at internal/storage/uow/batch_applier.go:142

	if err := r.spliceMetadataRefs(ctx); err != nil {
		return err
	}
	return r.runEndGate(ctx)
}

func (r *uowApplyRun) applyItem(ctx context.Context, index int) error {
	item := r.plan.Items[index]
	switch item.Kind {
	case publicops.ItemCreate:
		return r.applyCreate(ctx, index, item.Create)
	case publicops.ItemUpdate:
		return r.applyUpdate(ctx, index, item.Update)
	case publicops.ItemClose:
		return r.applyClose(ctx, index, item.Close)
	case publicops.ItemDepAdd:
		return r.applyDepAdd(ctx, index, item.DepAdd)
	}
	return fmt.Errorf("%w: apply batch item %d has unknown kind %q", publicops.ErrValidation, index, item.Kind)
}

// applyCreate mints one row through the same preparation, infra-type routing
// and error classification the single create and the create batch run, so an
// item's content rules ARE Lifecycle.Create's.
func (r *uowApplyRun) applyCreate(ctx context.Context, index int, item *publicops.CreateItem) error {
	itemErr := func(err error) error {
		return &publicops.ItemError{Index: index, Kind: publicops.ItemCreate, Key: item.Key, Err: err}
	}
	createContext, err := r.loadCreateContext(ctx)
	if err != nil {
		return err
	}
	prepared, err := storageissueops.PreparePublicCreateRequest(publicops.CreateRequest{
		Actor:         r.plan.Actor,
		Issue:         item.Issue,
		ForceIDPrefix: r.plan.ForceIDPrefix,
	}, storageissueops.PublicCreateContext{

View on GitHub (pinned to 71377f2769)

Solutions

  1. Upgrade the server/binary so it recognizes the item kind the client is sending
  2. Check client and server versions match (bd version on both ends)
  3. Inspect the batch payload at the reported index and remove/correct the unknown kind
  4. If hand-building batches, only use the documented publicops item constructors

Example fix

// before
items := []publicops.BatchItem{{Kind: "item_reorder", ...}} // unknown kind
// after
items := []publicops.BatchItem{{Kind: publicops.ItemUpdate, Update: ...}}
Defensive patterns

Strategy: validation

Validate before calling

supported := map[publicops.ItemKind]bool{
    publicops.ItemCreate: true, publicops.ItemUpdate: true,
    publicops.ItemClose: true, publicops.ItemDepAdd: true,
}
for i, it := range batch.Items {
    if !supported[it.Kind] { return fmt.Errorf("item %d: unsupported kind %q", i, it.Kind) }
}

Try / catch

err := applyBatch(ctx, batch)
if errors.Is(err, publicops.ErrValidation) {
    var itemErr *publicops.ItemError
    if errors.As(err, &itemErr) { /* inspect itemErr.Index / Kind */ }
}

Prevention

When it happens

Trigger: Submitting a batch (apply path) whose Items array contains an item whose Kind is not one of ItemCreate, ItemUpdate, ItemClose, ItemDepAdd — typically from a client built against a newer/older API version or hand-assembled payloads.

Common situations: Version skew between a CLI/SDK client and the server (client sends a newly added item kind the server does not know); corrupt or hand-edited batch payloads; forwarding a batch from a newer primary to an older replica.

Related errors


AI-assisted analysis of gastownhall/beads@71377f2769 (2026-08-30). Data as JSON: /api/errors/bf09798fcb115373. Report an issue: GitHub.