Nobody has started this yet — be first.
Business impact
BatchIngestResult.rejected_reason exists to tell a client why some of its events were rejected. A client (or an automated retry/alerting system) that checks rejected_reason to decide whether to back off would see "queue_full" on a batch where nothing was rejected at all — actively wrong information attached to a successful response. Anyone debugging "why does my monitoring say we're seeing queue_full errors when our own dashboards show 0 rejected events?" will lose real time chasing a field that's simply computed from the wrong variable.
Problem
BatchIngestResult.rejected_reason is supposed to tell a client why some of its events were rejected, but the final return BatchIngestResult(...) in ingest_batch derives it from the wrong local variable, so a fully successful batch can report a rejection reason that doesn't apply.
Current behavior
rejected_reason is computed as "queue_full" if accepted else None — it checks whether anything was accepted, not whether anything was rejected, so any batch with at least one accepted event reports "queue_full" regardless of the actual rejected count.
Expected behavior
rejected_reason should be "queue_full" when rejected > 0, and None when nothing was rejected — regardless of how many events were accepted.
Steps to reproduce
pytest practice_tickets/tests/test_ticket_09_rejected_reason.py -v — posts a small batch to a queue with plenty of room (nothing should ever be rejected) and checks the response body's rejected_reason field.Why this matters
"queue_full" if accepted else None and "queue_full" if rejected else None are one identifier apart and both "look plausible" next to a function that has both an accepted and a rejected local variable in scope — exactly the kind of near-miss that autocomplete or a fast typing session produces, and that a reviewer skimming for "does this reference a real variable" won't catch, because it does.
Suggested approach
Look at the final return BatchIngestResult(...) in app/routers/events.py::ingest_batch. rejected_reason is supposed to describe why events were rejected — which of the two local variables, accepted or rejected, actually answers "were any events rejected"?
Acceptance criteria
Verification
pytest practice_tickets/tests/test_ticket_09_rejected_reason.py -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/rejected-reason-wrong-variableFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/rejected-reason-wrong-variableSubmit 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:8000localhost:5432curl localhost:8000/healthzcurl localhost:8000/readyzWork the tickets in practice_tickets/tickets/ (ordered easy → hard); each names one dedicated test in practice_tickets/tests/:
pytest practice_tickets/tests/test_ticket_01_persisted_count.py -v # a single ticket
./practice_tickets/run_tickets.sh # all 20, clean pass/fail summary
TICKET-17 needs a real Postgres to run at all (it checks which column a value lands in, which no fake/in-memory DB backend can meaningfully verify) — set TEST_DATABASE_URL=postgresql://<you>@localhost/ingest_test before running it or the full suite; without it, that one test is skipped, not failed.
Level 1
Fix a bug
Read existing behaviour, correct it.