Reject zero execution attempts in ExecutionPlan steps - #6943
Conversation
|
There was a problem hiding this comment.
Important
The reproduction test is correct, but the implementation fix described in the PR body is not yet present. The PR title promises rejection of zero attempts, which will not happen until the guard in ExecutionPlan.ts is updated.
Reviewed changes
This PR adds a focused regression test for ExecutionPlan.make rejecting attempts: 0.
- Added
packages/effect/test/ExecutionPlanAttemptValidation.test.tswith a single synchronous test asserting that passingattempts: 0toExecutionPlan.makethrows. - Ran
pnpm test --run packages/effect/test/ExecutionPlanAttemptValidation.test.ts; the test fails exactly as expected, confirming it is a valid reproduction.
⚠️ Fix required before merge
ExecutionPlan.make currently guards the attempts check with if (options.attempts && options.attempts < 1) at packages/effect/src/ExecutionPlan.ts:182. Because 0 is falsy, the condition short-circuits and zero is accepted. The test in this PR correctly reproduces that bug.
To satisfy the PR's stated expected behavior, change the guard to explicitly distinguish absence from zero—for example, if (options.attempts !== undefined && options.attempts < 1). Also verify packages/effect/src/internal/executionPlan.ts:104-117, which uses truthy checks (step.attempts ? ...) to derive schedules; zero should not silently produce a default retry schedule there.
@v0 or keep the SHA fresh with Dependabot | Fix it ➔ | View workflow run | Using Kimi K2 (free via Pullfrog for OSS) | 𝕏

Summary
A step accepts attempts: 0 and then executes under default behavior instead of rejecting the impossible count.
Important
This PR starts with focused failing reproduction tests. Add the implementation fix to this same branch; CI is expected to fail until that fix is included.
Zero attempts bypasses positive-count validation
Module:
ExecutionPlanAudit ID:
core-a-f-execution-plan-zero-attemptsSeverity / confidence: medium / high
What happens
A step accepts attempts: 0 and then executes under default behavior instead of rejecting the impossible count.
Why it happens
Validation is guarded by if (options.attempts && ...), so zero skips the less-than-one check. Downstream truthiness handling also treats zero as absent.
Expected behavior
attempts is a count of executions for a step, and the constructor explicitly rejects values below one with "must be greater than 0".
Relevant implementation
These links and excerpts are pinned to audit base
c9b56ab507f224426ee8388dc450da447ec4715f.packages/effect/src/ExecutionPlan.ts:181-187packages/effect/src/internal/executionPlan.ts:94-117View problematic code at
packages/effect/src/ExecutionPlan.ts:181-187View exact lines on GitHub
View problematic code at
packages/effect/src/internal/executionPlan.ts:94-117View exact lines on GitHub
Reproduction
pnpm test --run packages/effect/test/ExecutionPlanAttemptValidation.test.tsObserved failure: A direct Node 24 source probe printed accepted for attempts: 0.
Implementation handoff
The initial reproduction tests on this branch are the regression specification for the implementation fix that should follow in this PR.
pnpm test --run packages/effect/test/ExecutionPlanAttemptValidation.test.tsAudit provenance
c9b56ab507f224426ee8388dc450da447ec4715fc9b56ab507f224426ee8388dc450da447ec4715fcore-a-f-execution-plan-zero-attempts