Nobody has started this yet — be first.
Business impact
PATCH /v1/jobs/{id} is documented as supporting partial updates: enable/disable or reschedule, independently. A caller rescheduling a job -- the single most common PATCH use case, e.g. "change this job's cron expression" -- sends only {"cron_expr": "..."} and expects the job's enabled state to be left alone. Instead, every such request fails outright with a database constraint violation. This means the reschedule half of the documented PATCH functionality is completely broken for any caller that follows the API as documented, which is the normal, idiomatic way to call a PATCH endpoint.
Problem
internal/store/jobs.go's Patch builds its UPDATE with enabled = $2, cron_expr = COALESCE($3, cron_expr), run_at = COALESCE($4, run_at). cron_expr and run_at correctly use COALESCE to fall back to the existing value when the caller didn't provide one. enabled does not -- it's assigned directly. When PatchJobParams.Enabled is nil (the caller omitted "enabled"), $2 is NULL, and jobs.enabled is NOT NULL, so the whole update is rejected by Postgres.
Current behavior
Patch({CronExpr: "*/5 * * * *"}, Enabled left nil) returns an error: "null value in column "enabled" of relation "jobs" violates not-null constraint".
Expected behavior
Patch should leave enabled unchanged when the caller doesn't specify it, exactly like it already does for cron_expr and run_at.
Steps to reproduce
curl -i -X PATCH localhost:8080/v1/jobs/1
-H 'Content-Type: application/json'
-d '{"cron_expr": "*/5 * * * *"}'
Why this matters
COALESCE(new_value, existing_value) is the standard SQL idiom for "update this column only if a new value was actually provided" in a single UPDATE statement without dynamically building the SQL per-request. Three columns needed this treatment here; only two got it.
Suggested approach
Compare the enabled line in the UPDATE to the cron_expr and run_at lines directly above and below it.
Acceptance criteria
Verification
TEST_DATABASE_URL="postgresql://chronos:chronos@localhost:5432/chronos?sslmode=disable" go test ./tickets/tests/... -run TestTicket07 -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/patch-enabled-coalesceFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/patch-enabled-coalesceSubmit 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 inhttp://localhost:8081app-1http://localhost:8082app-2http://localhost:8090curl localhost:8081/healthzcurl localhost:8081/readyzWork the tickets in tickets/docs/ (ordered easy → hard); each names one Go test in tickets/tests/. Most tickets need a real Postgres (tickets 4, 11, and 18 are pure-function tests and do not):
export TEST_DATABASE_URL="postgresql://chronos:chronos@localhost:5432/chronos?sslmode=disable"
go test ./tickets/tests/... -run TestTicket08 -v # a single ticket
./tickets/run_tickets.sh # all 20, clean pass/fail summary
Use -race when working on tickets 15, 16, or 17 (the concurrency ones) -- run_tickets.sh already does this for every ticket. Tickets 15 and 16 are adjacent bugs in the same function (pkg/leader/leader.go's lock-release path); fix ticket 16 first, since ticket 15's test keeps failing for ticket 16's reason until that one is fixed too.
Level 1
Fix a bug
Read existing behaviour, correct it.