{"record":{"id":"640bc77c37f7396d","repo":"dotnet/aspnetcore","slug":"circuit-state-this-statename-is-in-progress","errorCode":null,"errorMessage":"Circuit state ${this._stateName} is in progress","messagePattern":"Circuit state (.+?) is in progress","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/Components/Web.JS/src/Platform/Circuits/CircuitManager.ts","lineNumber":740,"sourceCode":"\n    reject(reason);\n  }\n\n  public isInprogress(): boolean {\n    return !!this._promise;\n  }\n\n  public currentProgress(): Promise<T> {\n    if (!this.isInprogress()) {\n      throw new Error(`Circuit state ${this._stateName} is not in progress`);\n    }\n\n    return this._promise!;\n  }\n\n  public transitionTo(newState: T): void {\n    if (this._promise) {\n      throw new Error(`Circuit state ${this._stateName} is in progress`);\n    }\n\n    this._lastValue = newState;\n  }\n\n  public lastValue() {\n    return this._lastValue;\n  }\n}\n","sourceCodeStart":722,"sourceCodeEnd":750,"githubUrl":"https://github.com/dotnet/aspnetcore/blob/3600ca084e9c8b5f4174fc5e747f4c52d2100806/src/Components/Web.JS/src/Platform/Circuits/CircuitManager.ts#L722-L750","documentation":"`transitionTo(newState)` synchronously moves a settled `CircuitState`'s last value (e.g. marking a circuit 'paused' when the connection drops without a formal pause). It refuses if `_promise` exists, because transitioning while an operation is in flight would race the async settlement — the value should be set by `complete()` instead.","triggerScenarios":"Calling `transitionTo()` on a `CircuitState` that currently has an in-flight operation (an unsettled `_promise` from `reset()`).","commonSituations":"Internal logic attempting to mark a state (e.g. paused) while a pause/resume/disconnect is still resolving; a connection-close handler racing with an explicit pause; re-entrant lifecycle calls during reconnect.","solutions":["Only call `transitionTo()` when `isInprogress()` is false — defer it until the operation settles.","If you need to set the value during an in-flight operation, let `complete()`/`fail()` set it instead.","Serialize lifecycle transitions so a new transition does not start before the previous one settles.","Review connection close/open handlers for races against explicit pause/resume calls."],"exampleFix":"// before\nthis._pausingState.transitionTo(true); // throws if a pause is in flight\n\n// after\nif (!this._pausingState.isInprogress()) {\n  this._pausingState.transitionTo(true);\n}","handlingStrategy":"validation","validationCode":"function safeTransition<T>(s: { isInprogress(): boolean; transitionTo(v: T): void }, v: T) {\n  if (!s.isInprogress()) s.transitionTo(v);\n}","typeGuard":null,"tryCatchPattern":"try { state.transitionTo(newState); }\ncatch (e) { if (/is in progress/.test(e.message)) { /* defer until settled */ return; } throw e; }","preventionTips":["Only transitionTo() when isInprogress() is false.","Let complete()/fail() set the value during in-flight operations.","Serialize lifecycle transitions.","Audit close/open handlers for races against pause/resume."],"tags":["circuit","state-machine","lifecycle","concurrency","blazor-server"],"backgroundTag":null,"analyzedSha":"3600ca084e9c8b5f4174fc5e747f4c52d2100806","analyzedAt":"2026-08-11T16:32:30.678Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}