Repository navigation
Reject a negative spawn_rate in /swarm instead of reporting a successful start - #3538
Merged
cyberw merged 1 commit intoOct 4, 2026
Merged
Conversation
The /swarm guard used `not spawn_rate`, which only catches None and 0, so a negative rate was forwarded to runner.start() and raised inside the spawned greenlet after the endpoint had already answered success:true.
This was referenced Oct 12, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
/swarmvalidateduser_countfor negativity but only checkedspawn_ratefor falsiness(
not spawn_rate), so a negativespawn_rateproduced{"success": true, "message": "Swarming started"}and then killed the spawned greenlet with
ValueError: spawn_rate must be > 0, got -5.0fromnew_dispatch()— leavingrunner.state == ready,runner.user_count == 0andunhandled_greenlet_exception == True, with the failure only visible in the log.Fixes #3537.
Change
locust/web.py— one condition, mirroring the--spawn-ratecontract (gt_zero(float)inlocust/argument_parser.py) and the adjacentuser_count < 0check:spawn_rate is None or spawn_rate <= 0rejects exactly whatnot spawn_raterejected (Noneand0) plus the negatives, so the existing error message and status are reused unchanged. Theshape-class branch returns before this check, so
LoadShaperuns that omitspawn_rateareunaffected.
locust/test/test_web.py—test_swarm_negative_spawn_rate_returns_clean_error(), the missingcounterpart to
test_swarm_negative_user_count_returns_clean_error().How it was checked
On
masterat80c03a87, Python 3.11, Windows:FAILED ... AssertionError: True is not false(i.e./swarmrepliedsuccess: true).pytest locust/test/test_web.py -k swarm -qafter the change: 22 passed (includes theshape-class and
spawn_rate=0cases).pytest locust/test/test_web.py -qfailure set compared against a run of the pristine tip on thesame interpreter: identical 16 failed / 1 error, all pre-existing Windows-only ones
(
TestWebUIAuth,TestWebUIWithTLS,TestWebUIFullHistory); the only difference is40 passed -> 41 passed.ruff check locust/: all checks passed;ruff format --check: already formatted.mypy locust/: 5 errors, byte-identical to the tip baseline (WindowsSIGWINCH/resource/openptyattribute errors inlocust/stats.py,locust/test/__init__.py,locust/test/subprocess_utils.py).Follow-up to #3527 / #3528: the dispatcher now rejects a non-positive rate, this makes the web layer
report it as an error instead of a successful start.
Drafted with AI assistance in this session; no human reviewed it before submission.