{"record":{"id":"905ca3248460e971","repo":"App-vNext/Polly","slug":"cannot-add-any-more-resilience-strategies-to-the-b","errorCode":null,"errorMessage":"Cannot add any more resilience strategies to the builder after it has been used to build a pipeline once.","messagePattern":"Cannot add any more resilience strategies to the builder after it has been used to build a pipeline once\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Polly.Core/ResiliencePipelineBuilderBase.cs","lineNumber":112,"sourceCode":"    /// </summary>\n    /// <value>The default value is a validation function that uses data annotations for validation.</value>\n    /// <remarks>\n    /// The validator should throw <see cref=\"ValidationException\"/> when the validated instance is invalid.\n    /// </remarks>\n    /// <exception cref=\"ArgumentNullException\">Thrown when the attempting to assign <see langword=\"null\"/> to this property.</exception>\n    internal Action<ResilienceValidationContext> Validator { get; private protected set; } = ValidationHelper.ValidateObject;\n\n    [RequiresUnreferencedCode(Constants.OptionsValidation)]\n    internal void AddPipelineComponent(Func<StrategyBuilderContext, PipelineComponent> factory, ResilienceStrategyOptions options)\n    {\n        Guard.NotNull(factory);\n        Guard.NotNull(options);\n\n        Validator(new ResilienceValidationContext(options, $\"The '{TypeNameFormatter.Format(options.GetType())}' are invalid.\"));\n\n        if (_used)\n        {\n            throw new InvalidOperationException(\"Cannot add any more resilience strategies to the builder after it has been used to build a pipeline once.\");\n        }\n\n        _entries.Add(new(factory, options));\n    }\n\n    internal PipelineComponent BuildPipelineComponent()\n    {\n        Validator(new(this, $\"The '{nameof(ResiliencePipelineBuilder)}' configuration is invalid.\"));\n\n        _used = true;\n\n        var components = _entries.ConvertAll(CreateComponent);\n\n        if (components.Count == 0)\n        {\n            return PipelineComponent.Empty;\n        }\n","sourceCodeStart":94,"sourceCodeEnd":130,"githubUrl":"https://github.com/App-vNext/Polly/blob/d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac/src/Polly.Core/ResiliencePipelineBuilderBase.cs#L94-L130","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nvar builder = new ResiliencePipelineBuilder().AddRetry(new());\nvar pipeline = builder.Build();\nbuilder.AddCircuitBreaker(new()); // throws\n\n// after\nvar pipeline = new ResiliencePipelineBuilder()\n    .AddRetry(new())\n    .AddCircuitBreaker(new())\n    .Build(); // configure fully, build once","handlingStrategy":"validation","validationCode":"// Track whether you have built:\nResiliencePipeline? built = null;\nvoid AddMore() {\n    if (built != null) throw new InvalidOperationException(\"Builder already used; create a new one.\");\n    builder.AddStrategy(...);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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."],"tags":["builder","invalid-operation","single-use","lifecycle","polly-core"],"backgroundTag":null,"analyzedSha":"d0e46bdb1ee11ea50d0e4b6846d2633d6bc09bac","analyzedAt":"2026-08-13T16:36:01.959Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}