App-vNext/Polly · error · InvalidOperationException
Cannot add any more resilience strategies to the builder aft
Error message
Cannot add any more resilience strategies to the builder after it has been used to build a pipeline once.
What it means
Once ResiliencePipelineBuilderBase.BuildPipelineComponent() runs, the internal _used flag is set and subsequent AddPipelineComponent calls throw InvalidOperationException. Builders are single-use: the built ResiliencePipeline captures the strategy chain, so mutating the builder afterward would not affect the already-built pipeline and is forbidden to keep semantics clear.
Source
Thrown at src/Polly.Core/ResiliencePipelineBuilderBase.cs:112
/// </summary>
/// <value>The default value is a validation function that uses data annotations for validation.</value>
/// <remarks>
/// The validator should throw <see cref="ValidationException"/> when the validated instance is invalid.
/// </remarks>
/// <exception cref="ArgumentNullException">Thrown when the attempting to assign <see langword="null"/> to this property.</exception>
internal Action<ResilienceValidationContext> Validator { get; private protected set; } = ValidationHelper.ValidateObject;
[RequiresUnreferencedCode(Constants.OptionsValidation)]
internal void AddPipelineComponent(Func<StrategyBuilderContext, PipelineComponent> factory, ResilienceStrategyOptions options)
{
Guard.NotNull(factory);
Guard.NotNull(options);
Validator(new ResilienceValidationContext(options, $"The '{TypeNameFormatter.Format(options.GetType())}' are invalid."));
if (_used)
{
throw new InvalidOperationException("Cannot add any more resilience strategies to the builder after it has been used to build a pipeline once.");
}
_entries.Add(new(factory, options));
}
internal PipelineComponent BuildPipelineComponent()
{
Validator(new(this, $"The '{nameof(ResiliencePipelineBuilder)}' configuration is invalid."));
_used = true;
var components = _entries.ConvertAll(CreateComponent);
if (components.Count == 0)
{
return PipelineComponent.Empty;
}
View on GitHub (pinned to d0e46bdb1e)
Solutions
- Configure all strategies before calling Build(); build exactly once per builder instance.
- If you need a variant pipeline, create a new builder (optionally via the copy constructor) instead of mutating a used one.
- Cache the built ResiliencePipeline, not the builder, when you need to reuse the result.
Example fix
// before
var builder = new ResiliencePipelineBuilder().AddRetry(new());
var pipeline = builder.Build();
builder.AddCircuitBreaker(new()); // throws
// after
var pipeline = new ResiliencePipelineBuilder()
.AddRetry(new())
.AddCircuitBreaker(new())
.Build(); // configure fully, build once Defensive patterns
Strategy: validation
Validate before calling
// Track whether you have built:
ResiliencePipeline? built = null;
void AddMore() {
if (built != null) throw new InvalidOperationException("Builder already used; create a new one.");
builder.AddStrategy(...);
} Prevention
- Configure all strategies in one fluent chain, then call Build() exactly once.
- Cache the built ResiliencePipeline, not the builder.
- To produce variants, construct fresh builders rather than reusing a used one.
When it happens
Trigger: Calling .AddRetry(...)/.AddCircuitBreaker(...)/etc. on a builder after .Build() has already been called on it. Also reusing a builder that DI helper pipelines (AddResiliencePipeline) internally built.
Common situations: Storing a builder in a static/DI singleton, building it, then trying to append strategies later; fluent chains split across methods where one branch calls Build() early; passing the same builder to two callers who both configure and build.
Related errors
- TaskExecution is not initialized.
- Unable to accept outcome for a task that is not completed.
- This instance of 'CircuitBreakerStateProvider' is already in
- No predicates were configured. There must be at least one pr
- Disposing this resilience pipeline is not allowed because it
AI-assisted analysis of App-vNext/Polly@d0e46bdb1e (2026-08-13).
Data as JSON: /api/errors/905ca3248460e971.
Report an issue: GitHub.