Nobody has started this yet — be first.
Business impact
This is in the reusable state-machine library, so it affects every future caller, not just payments. A zero-duration Timeout schedules a deadline of "right now" -- the sweeper could claim and fire it before the very transaction that created it has even returned a response to the caller. For a payment machine specifically, imagine someone later adds Timeout("some_state", cfg.SomeDuration, "give_up") and SomeDuration comes from a misconfigured env var that parses to 0 -- instead of a clear startup error ("duration must be positive"), the app starts fine and then behaves nondeterministically in production, which is a much more expensive class of bug to diagnose.
Problem
Builder.Timeout(state, 0, event) is silently accepted by Build() instead of being rejected as invalid.
Current behavior
A zero-duration Timeout call, followed by Build(), returns a nil error -- but it should not.
Expected behavior
Build() should return an error for a zero-duration timeout, exactly the way it already does for a negative one.
Steps to reproduce
_, err := statemachine.New("widget"). State("a"). State("b", statemachine.Terminal()). Transition("a", "go", "b", nil, nil). Timeout("a", 0, "go"). Build() // err is nil -- but it shouldn't be
Why this matters
Look at the validation in Builder.Timeout: it already has a branch that rejects an invalid duration and produces a *BuildError naming the state and the bad duration. The bug is purely in which durations that branch considers invalid.
Suggested approach
Compare the current condition against the error message right next to it -- it says "must be positive." Is 0 positive?
Acceptance criteria
Verification
go test ./tickets/tests/... -run TestTicket02 -v
Hints (0/2)
Try it without hints first — the reading is the exercise.
Working on this ticket
Work on a branch named for the ticket — that's what you'll submit.
Branch off your fork
Sign in to create it automatically, or do it yourself:
$git checkout -b fix/zero-duration-timeout-acceptedFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/zero-duration-timeout-acceptedSubmit it below
Paste your fork URL and the branch name, with a short write-up of the root cause.
Questions
Ask about anything unclear in the ticket — the maintainer and anyone who has solved it can answer. Please don't post full solutions.
Sign in to ask a question or reply.
Sign indocker composepaystate/paystate/go.modreplace reliable => ../reliabledocker compose up --buildpaystate/context: ..docker-compose.ymlCREATED_TIMEOUTAUTHORIZED_TIMEOUTWork the tickets in tickets/docs/ (ticket-01 through ticket-25); each names one Go test in tickets/tests/:
TEST_DATABASE_URL=postgresql://... go test ./tickets/tests/... -run TestTicket01 -v # a single ticket
TEST_DATABASE_URL=postgresql://... ./tickets/run_tickets.sh # all 25, clean pass/fail summary
Tickets that don't touch Postgres (02, 03, 04, 05, 06, 14, 15, 24) run fine without TEST_DATABASE_URL set; the rest report FAIL with a "TEST_DATABASE_URL not set" message if it's missing. make test-race runs the full go test -race -p 1 ./... suite the same way.
Level 1
Fix a bug
Read existing behaviour, correct it.