weaviate/weaviate · error

batch delete params: %w

Error message

batch delete params: %w

What it means

Authorization succeeded, but converting the protobuf BatchDeleteRequest into internal batch delete params failed. batchDeleteParamsFromProto validates the filter, tenant, and class (via classGetterWithAuthz) and returns an error for malformed or unresolvable delete specifications.

Source

Thrown at adapters/handlers/grpc/v1/service.go:202

	replicationProperties := extractReplicationProperties(req.ConsistencyLevel)

	tenant := ""
	if req.Tenant != nil {
		tenant = *req.Tenant
	}

	if req.Collection, _, err = namespacing.Resolve(principal, s.schemaManager, s.config.Namespaces.Enabled, req.Collection); err != nil {
		return nil, err
	}

	if err := s.authorizer.Authorize(ctx, principal, authorization.DELETE, authorization.ShardsData(req.Collection, tenant)...); err != nil {
		return nil, err
	}

	params, err := batchDeleteParamsFromProto(req, s.classGetterWithAuthzFunc(ctx, principal, tenant), s.config.Namespaces.Enabled, principal)
	if err != nil {
		return nil, fmt.Errorf("batch delete params: %w", err)
	}

	response, err := s.batchManager.DeleteObjectsFromGRPCAfterAuth(ctx, principal, params, replicationProperties, tenant)
	if err != nil {
		return nil, fmt.Errorf("batch delete: %w", err)
	}

	result, err := batchDeleteReplyFromObjects(response, req.Verbose, principal)
	if err != nil {
		return nil, fmt.Errorf("batch delete reply: %w", err)
	}
	result.Took = float32(time.Since(before).Seconds())

	return result, nil
}

// BatchObjects handles end-to-end batch object creation. It accepts N objects in the request and forwards them to the internal
// batch objects logic. It blocks until a response is retrieved from the internal APIs whereupon it returns the response to the client.

View on GitHub (pinned to 75aa4b6d11)

Solutions

  1. Check the wrapped error for the exact invalid field in the request
  2. Validate the where-filter path/property names against the current schema
  3. Confirm the tenant exists and matches case exactly
  4. Regenerate client stubs to match the server proto version

Example fix

// before: filter on removed property
req.Filter = &pb.Filters{Target: &pb.Filters_OnProperty{OnProperty: "oldName"}}
// after: filter on a valid, filterable property
req.Filter = &pb.Filters{Target: &pb.Filters_OnProperty{OnProperty: "status"}}
Defensive patterns

Strategy: validation

Validate before calling

func validateBatchDelete(req *pb.BatchDeleteRequest, schema Schema, tenant string) error {
  if req.Collection == "" { return errors.New("collection required") }
  if _, ok := schema[req.Collection]; !ok { return fmt.Errorf("unknown collection %q", req.Collection) }
  if tenant == "" { return errors.New("tenant required") }
  if req.Filter == nil { return errors.New("where-filter required for batch delete") }
  return nil
}

Type guard

func hasFilter(req *pb.BatchDeleteRequest) bool { return req != nil && req.Filter != nil }

Try / catch

resp, err := client.BatchDelete(ctx, req)
if err != nil && strings.Contains(err.Error(), "batch delete params") {
  return fmt.Errorf("rejecting invalid delete request: %w", err)
}

Prevention

When it happens

Trigger: BatchDelete with an invalid where-filter structure, referencing a non-existent collection or property, tenant that doesn't exist, filter on a non-filterable datatype, or a class the authenticated user cannot read (class getter applies authz).

Common situations: Filter built by hand against a stale proto; property renamed in schema; tenant name case mismatch; referencing array/object properties not supported by the filter; server-side namespacing feature enabled while client sends raw names.

Related errors


AI-assisted analysis of weaviate/weaviate@75aa4b6d11 (2026-09-04). Data as JSON: /api/errors/6a001b6fac6c6ce5. Report an issue: GitHub.