{"record":{"id":"6a001b6fac6c6ce5","repo":"weaviate/weaviate","slug":"batch-delete-params-w","errorCode":null,"errorMessage":"batch delete params: %w","messagePattern":"batch delete params: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"adapters/handlers/grpc/v1/service.go","lineNumber":202,"sourceCode":"\n\treplicationProperties := extractReplicationProperties(req.ConsistencyLevel)\n\n\ttenant := \"\"\n\tif req.Tenant != nil {\n\t\ttenant = *req.Tenant\n\t}\n\n\tif req.Collection, _, err = namespacing.Resolve(principal, s.schemaManager, s.config.Namespaces.Enabled, req.Collection); err != nil {\n\t\treturn nil, err\n\t}\n\n\tif err := s.authorizer.Authorize(ctx, principal, authorization.DELETE, authorization.ShardsData(req.Collection, tenant)...); err != nil {\n\t\treturn nil, err\n\t}\n\n\tparams, err := batchDeleteParamsFromProto(req, s.classGetterWithAuthzFunc(ctx, principal, tenant), s.config.Namespaces.Enabled, principal)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"batch delete params: %w\", err)\n\t}\n\n\tresponse, err := s.batchManager.DeleteObjectsFromGRPCAfterAuth(ctx, principal, params, replicationProperties, tenant)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"batch delete: %w\", err)\n\t}\n\n\tresult, err := batchDeleteReplyFromObjects(response, req.Verbose, principal)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"batch delete reply: %w\", err)\n\t}\n\tresult.Took = float32(time.Since(before).Seconds())\n\n\treturn result, nil\n}\n\n// BatchObjects handles end-to-end batch object creation. It accepts N objects in the request and forwards them to the internal\n// batch objects logic. It blocks until a response is retrieved from the internal APIs whereupon it returns the response to the client.","sourceCodeStart":184,"sourceCodeEnd":220,"githubUrl":"https://github.com/weaviate/weaviate/blob/75aa4b6d11f8818305aafd4440b4e32794f7ca04/adapters/handlers/grpc/v1/service.go#L184-L220","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["Check the wrapped error for the exact invalid field in the request","Validate the where-filter path/property names against the current schema","Confirm the tenant exists and matches case exactly","Regenerate client stubs to match the server proto version"],"exampleFix":"// before: filter on removed property\nreq.Filter = &pb.Filters{Target: &pb.Filters_OnProperty{OnProperty: \"oldName\"}}\n// after: filter on a valid, filterable property\nreq.Filter = &pb.Filters{Target: &pb.Filters_OnProperty{OnProperty: \"status\"}}","handlingStrategy":"validation","validationCode":"func validateBatchDelete(req *pb.BatchDeleteRequest, schema Schema, tenant string) error {\n  if req.Collection == \"\" { return errors.New(\"collection required\") }\n  if _, ok := schema[req.Collection]; !ok { return fmt.Errorf(\"unknown collection %q\", req.Collection) }\n  if tenant == \"\" { return errors.New(\"tenant required\") }\n  if req.Filter == nil { return errors.New(\"where-filter required for batch delete\") }\n  return nil\n}","typeGuard":"func hasFilter(req *pb.BatchDeleteRequest) bool { return req != nil && req.Filter != nil }","tryCatchPattern":"resp, err := client.BatchDelete(ctx, req)\nif err != nil && strings.Contains(err.Error(), \"batch delete params\") {\n  return fmt.Errorf(\"rejecting invalid delete request: %w\", err)\n}","preventionTips":["Validate filter paths against the live schema before deleting","Match tenant names exactly (case-sensitive)","Fetch the class via an authorized client so mismatches surface locally first"],"tags":["grpc","batch-delete","parameter-validation"],"backgroundTag":"grpc-request-params-invalid","analyzedSha":"75aa4b6d11f8818305aafd4440b4e32794f7ca04","analyzedAt":"2026-09-04T14:58:20.392Z","contentChangedAt":"2026-09-04T14:58:20.392Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}