{"record":{"id":"e902daaca9f0f14c","repo":"App-vNext/Polly","slug":"no-predicates-were-configured-there-must-be-at-le","errorCode":null,"errorMessage":"No predicates were configured. There must be at least one predicate added.","messagePattern":"No predicates were configured\\. There must be at least one predicate added\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Polly.Core/PredicateBuilder.TResult.cs","lineNumber":128,"sourceCode":"    {\n        comparer ??= EqualityComparer<TResult>.Default;\n\n        return HandleResult(r => comparer.Equals(r, result));\n    }\n\n    /// <summary>\n    /// Builds the predicate.\n    /// </summary>\n    /// <returns>An instance of predicate delegate.</returns>\n    /// <exception cref=\"InvalidOperationException\">Thrown when no predicates were configured using this builder.</exception>\n    /// <remarks>\n    /// The returned predicate will return <see langword=\"true\"/> if any of the configured predicates return <see langword=\"true\"/>.\n    /// Please be aware of the performance penalty if you register too many predicates with this builder. In such case, it's better to create your own predicate\n    /// manually as a delegate.\n    /// </remarks>\n    public Predicate<Outcome<TResult>> Build() => _predicates.Count switch\n    {\n        0 => throw new InvalidOperationException(\"No predicates were configured. There must be at least one predicate added.\"),\n        1 => _predicates[0],\n        _ => CreatePredicate([.. _predicates]),\n    };\n\n    internal Func<TArgs, ValueTask<bool>> Build<TArgs>()\n        where TArgs : IOutcomeArguments<TResult>\n    {\n        var predicate = Build();\n\n        return args => new ValueTask<bool>(predicate(args.Outcome));\n    }\n\n    private static Predicate<Outcome<TResult>> CreatePredicate(Predicate<Outcome<TResult>>[] predicates) =>\n        outcome =>\n        {\n            foreach (var predicate in predicates)\n            {\n                if (predicate(outcome))","sourceCodeStart":110,"sourceCodeEnd":146,"githubUrl":"https://github.com/App-vNext/Polly/blob/d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac/src/Polly.Core/PredicateBuilder.TResult.cs#L110-L146","documentation":"PredicateBuilder<TResult>.Build() throws InvalidOperationException when _predicates is empty. The builder is the fluent API for declaring which outcomes/exceptions a strategy handles; a strategy must handle at least one outcome, so an empty predicate set is rejected at Build() time rather than silently matching nothing.","triggerScenarios":"Constructing a PredicateBuilder, never calling .Handle<TException>(), .HandleResult(...), .Of<T>() etc., and then assigning builder.Build() to RetryStrategyOptions.ShouldHandle, then Build()ing the pipeline.","commonSituations":"Building predicates conditionally where every branch is skipped; refactoring that deletes the only .Handle call; copy-pasting a builder setup and forgetting the predicate lines.","solutions":["Add at least one predicate via .Handle<ExceptionType>(), .HandleResult(predicate), or .Of<TResult>() before calling Build().","Prefer the PredicateBuilder fluent chain inline at the options site so the empty case is visually obvious.","If you genuinely want to handle nothing, do not add the strategy at all rather than passing an empty predicate."],"exampleFix":"// before\nvar predicates = new PredicateBuilder<HttpResponseMessage>();\noptions.ShouldHandle = predicates.Build(); // throws\n\n// after\nvar predicates = new PredicateBuilder<HttpResponseMessage>()\n    .Handle<HttpRequestException>()\n    .HandleResult(r => r.StatusCode >= System.Net.HttpStatusCode.InternalServerError);\noptions.ShouldHandle = predicates.Build();","handlingStrategy":"validation","validationCode":"// Guard the builder before Build():\nif (builder == null || /* no Handle added */) {\n    throw new InvalidOperationException(\"Add at least one predicate before building.\");\n}\n// Or check the strategy: most *StrategyOptions have a non-null default ShouldHandle, so\n// only call builder.Build() when you have explicitly added predicates.","typeGuard":null,"tryCatchPattern":"try { var predicate = builder.Build(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"No predicates\")) {\n    // add a default predicate and rebuild, or skip the strategy\n}","preventionTips":["Always chain at least one .Handle<>()/.HandleResult()/.Of<T>() before .Build().","Build predicates inline at the options site so an empty chain is visible.","If conditional predicate construction can yield zero, fall back to a sensible default predicate."],"tags":["predicate-builder","validation","invalid-operation","configuration","polly-core"],"backgroundTag":null,"analyzedSha":"d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac","analyzedAt":"2026-08-13T16:36:01.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}