ScopedProgressIndicator stores whileStart and whileDelay swapped in showWhile
- Dominant language
- TypeScript
- Stars
- 193k
- Forks
- 42.4k
- PR merge metrics
- PR metrics pending
Description
### Bug description
`ScopedProgressIndicator.showWhile` (`src/vs/workbench/services/progress/browser/progressIndicator.ts`) constructs its while-state with two arguments swapped:
```ts
new ProgressIndicatorState.While(promise, delay || 0, Date.now())
```
against the constructor signature
```ts
constructor(whilePromise, whileStart, whileDelay)
```
so `whileStart` holds the configured delay and `whileDelay` holds the creation timestamp. Introduced when scoped progress was made generic in early 2022 (commit `3cdf4d82eadb`), line 305 remains the only construction site.
Today this produces no visible misbehavior only because the replay formula happens to be symmetric under the swap: `whileDelay - (Date.now() - whileStart)` evaluates to the same number either way. The damage is latent:
- `whileDelay` is fed to a `> 0` guard as a wall-clock timestamp, so the guard can never be false;
- any future consumer of `whileStart`/`whileDelay` reading them per their names gets wrong values;
- the replay arithmetic silently depends on an accidental algebraic coincidence between the constructor contract and one call site.
### Steps to reproduce
Read line ~305 against the `ProgressIndicatorState.While` constructor at ~129: the second argument is the configured delay, the third is `Date.now()`, reversing the declared parameter order.
### Expected behavior
`whileStart` receives the wall-clock start time and `whileDelay` receives the configured delay, matching the parameter names and every other use of those fields.
### Version tested
Commit `3746c6426bc6` on `main`; verified by executing compiled output and by a new unit assertion pinning the stored fields. A one-line fix plus regression test is ready.
Contributor guide
Assessment
This issue has not been assessed yet.