{"record":{"id":"c0d29ddcd6b28d3b","repo":"hashicorp/nomad","slug":"evals-cannot-be-deleted-by-both-id-and-filter","errorCode":null,"errorMessage":"evals cannot be deleted by both ID and filter","messagePattern":"evals cannot be deleted by both ID and filter","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"nomad/eval_endpoint.go","lineNumber":475,"sourceCode":"\t}\n\tdefer metrics.MeasureSince([]string{\"nomad\", \"eval\", \"delete\"}, time.Now())\n\n\t// This RPC endpoint is very destructive and alters Nomad's core state,\n\t// meaning only those with management tokens can call it.\n\tif aclObj, err := e.srv.ResolveACL(args); err != nil {\n\t\treturn err\n\t} else if !aclObj.IsManagement() {\n\t\treturn structs.ErrPermissionDenied\n\t}\n\n\tif args.Filter != \"\" && !e.srv.peersCache.ServersMeetMinimumVersion(\n\t\te.srv.Region(), minVersionEvalDeleteByFilter, true) {\n\t\treturn fmt.Errorf(\n\t\t\t\"all servers must be running version %v or later to delete evals by filter\",\n\t\t\tminVersionEvalDeleteByFilter)\n\t}\n\tif args.Filter != \"\" && len(args.EvalIDs) > 0 {\n\t\treturn fmt.Errorf(\"evals cannot be deleted by both ID and filter\")\n\t}\n\tif args.Filter == \"\" && len(args.EvalIDs) == 0 {\n\t\treturn fmt.Errorf(\"evals must be deleted by either ID or filter\")\n\t}\n\n\t// The eval broker must be disabled otherwise Nomad's state will likely get\n\t// wild in a very un-fun way.\n\tif e.srv.evalBroker.Enabled() {\n\t\treturn errors.New(\"eval broker is enabled; eval broker must be paused to delete evals\")\n\t}\n\n\tif args.Filter != \"\" {\n\t\tcount, index, err := e.deleteEvalsByFilter(args)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\n\t\t// Update the index and return.","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/nomad/eval_endpoint.go#L457-L493","documentation":"Returned by Evaluations.Delete when the caller supplies both a filter and explicit eval IDs. The API requires delete requests to be unambiguous: either select evals by filter OR by ID list, never both in the same call.","triggerScenarios":"Sending an EvalDeleteRequest with args.Filter set to a non-empty string AND len(args.EvalIDs) > 0.","commonSituations":"Client code that always populates EvalIDs and also adds a status filter; UI/tooling that combines 'selected evals' with an active filter expression without clearing one of them.","solutions":["Remove either the Filter or the EvalIDs field from the request","Issue two separate delete calls: one by ID, one by filter"],"exampleFix":"// before\nreq := &structs.EvalDeleteRequest{EvalIDs: ids, Filter: \"Status == complete\"}\n// after\nreq := &structs.EvalDeleteRequest{EvalIDs: ids} // drop the filter","handlingStrategy":"validation","validationCode":"if filter != \"\" && len(ids) > 0 { return errors.New(\"specify either filter or eval IDs, not both\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Build delete requests with exactly one selection criterion","Clear the filter when acting on user-selected eval IDs","Write a small request-builder helper that enforces XOR semantics"],"tags":["nomad","rpc","validation","request-conflict"],"backgroundTag":"conflicting-request-parameters","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}