Nobody has started this yet — be first.
Business impact
POST /admin/routes/reload is the operational escape hatch for pushing route changes without a redeploy. If someone makes a typo in routes.yaml -- a bad indent, a field that fails a validator, a missing required key -- the reload endpoint does not fail loudly; it silently succeeds with an empty route table. Every route disappears, every proxied request starts 404ing, and the response the operator who ran the reload actually sees gives no indication anything went wrong. This turns a typo into a full outage that looks, from the caller's side, like a successful operation.
Problem
load_routes_file() wraps RouteTableFile.model_validate(raw) in a bare try/except Exception, logs a warning, and returns [] on any validation failure -- the exact same silent-empty-table behavior that is correctly (and intentionally) used for the missing-file case just above it, now also covering the completely different case of "the file exists but is broken."
Current behavior
A routes.yaml with an invalid route (e.g. a path_prefix that does not start with /, which RouteConfig's own validator already rejects) makes load_routes_file() return [] and log a warning, exactly as if the file did not exist at all -- the caller cannot tell "nothing configured yet" apart from "configured, and broken."
Expected behavior
A missing routes file still results in an empty table (the existing, correct, documented behavior for a fresh gateway). A file that exists but fails to parse or validate should raise, loudly, so POST /admin/routes/reload returns an error status instead of 200 with an empty list, and a broken file at startup should fail the process instead of silently booting into an empty, useless state.
Steps to reproduce
Why this matters
"Return an empty result and log a warning" is the right shape of behavior for the missing-file branch immediately above -- that is a genuinely benign, expected state. Reusing that shape for a validation failure conflates "there is nothing here" with "there is something here and it is broken," which are operationally opposite situations requiring opposite responses (one is fine to ignore, the other needs to block the operation and page someone).
Suggested approach
Look at what currently happens to the except Exception block's exception -- it is logged and discarded. Decide what load_routes_file should do instead, and check how app/admin/routes.py::reload_routes and app/main.py's startup path each currently call this function, so a fix here surfaces correctly at both call sites.
Acceptance criteria
Verification
pytest practice_tickets/tests/test_ticket_07_loader_swallows_validation_errors.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/loader-swallows-validation-errorsFix it and commit
Meet every acceptance criterion, and add a test that would have caught this.
Push the branch
$git push -u origin fix/loader-swallows-validation-errorsSubmit 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:8080fast_echo/echo/.../large/{size_mb}slow_upstream/delay/{s}/flaky/always-downroutes.yamlcurl localhost:8080/healthzcurl localhost:8080/readyz/admin/*Authorization: Bearer <GATEWAY_ADMIN_TOKEN>You do not need Docker running at all to work the tickets — the test suite fakes Redis with fakeredis (plus lupa for real Lua-script support), so everything runs against a plain virtualenv:
python3 -m venv .venv && .venv/bin/pip install -r requirements-dev.txt
.venv/bin/pytest practice_tickets/tests/test_ticket_09_breaker_threshold_off_by_one.py -v # a single ticket
./practice_tickets/run_tickets.sh # all 15, clean pass/fail summary
./practice_tickets/run_tickets.sh 06 09 15 # just a few, by number
All 15 tests fail at the start; as you fix each ticket in app/, its test (and only its test) should flip to passing. .venv/bin/pytest tests/ runs the project's own main suite — as of writing it shows 8 pre-existing failures caused by ticket bugs 02, 04, 06, and 09; fixing those tickets fixes those failures too, not a separate task.
Level 1
Fix a bug
Read existing behaviour, correct it.