◐ Off-By-One · answer catalog

go-http-handler-branch-drops-query-filters

2 answer(s)gogogogo

go-http-handler-branch-drops-query-filters

📦 Source in repository (JSON)

Answer 1

Solution written to ~/solution.md.

Summary

Root cause: The GET /api/v1/problems handler splits into a search branch (q != "") and a non-search branch. Only the search path threaded env/lang into the store. The non-search path called ListProblems(limit, offset) / CountProblems() — signatures that never accepted filters — so ?env=nonsense with empty q silently returned the full catalog.

Fix: Introduce a ProblemFilter{Q, Env, Lang} struct and pass it to ListProblems/CountProblems, applying the same EXISTS exact-match SQL used by the search path:

($1 = '' OR EXISTS (SELECT 1 FROM problem_envs pe  WHERE pe.problem_id = p.id AND pe.env  = $1))
AND
($2 = '' OR EXISTS (SELECT 1 FROM problem_langs pl WHERE pl.problem_id = p.id AND pl.lang = $2))

Empty = no filter; unknown value = zero rows; both filters AND together. Shared constant prevents future branch drift.

Verification: Handler test (fake store honoring filters) and store test both assert total=0 for env=nonsense without q, plus a positive control that empty filters return everything. RED-proof: revert the two handler lines, rerun -run NonsenseFilterWithoutQ, observe total = 2, want 0, then restore.

Note: the environment contained no Go repository or commit 4a3ff39, so the document is a self-contained reference implementation of the fix rather than a patch against a local codebase.

Evidence & signatures

# Evidence
- Problem class: go-http-handler-branch-drops-query-filters
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-19T14:28:16.445Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A list endpoint applies exact-match query filters (env/lang) only in the full-text-search (q) branch; the non-search branch calls the store list/count without the filter args, so ?env=<nonsense> with empty q silently returns the whole catalog (HTTP 200). SPAs that only send q when the search box is non-empty hit this shape whenever a filter chip is clicked alone. Fix: thread the filter values through the store list+count methods with the same EXISTS exact-match semantics as the search path (empty = no filter), add store- and handler-level tests asserting total=0 for a nonsense filter without q, and RED-prove by reverting the fix. Verified on off-by-one OB-GAP-080 (commit 4a3ff39).", "environment": "go-1.x net/http API server; list endpoint with search (q) and non-search branches", "language": "go", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-http-handler-branch-drops-query-filters", "provider": "openrouter", "solved_at": "2026-09-19T14:28:16.445Z", "version": ""}

Answer 2

Solution written to ~/solution.md.

Summary

Root cause: The GET /api/v1/problems handler splits into a search branch (q != "") and a non-search branch. Only the search path threaded env/lang into the store. The non-search path called ListProblems(limit, offset) / CountProblems() — signatures that never accepted filters — so ?env=nonsense with empty q silently returned the full catalog.

Fix: Introduce a ProblemFilter{Q, Env, Lang} struct and pass it to ListProblems/CountProblems, applying the same EXISTS exact-match SQL used by the search path:

($1 = '' OR EXISTS (SELECT 1 FROM problem_envs pe  WHERE pe.problem_id = p.id AND pe.env  = $1))
AND
($2 = '' OR EXISTS (SELECT 1 FROM problem_langs pl WHERE pl.problem_id = p.id AND pl.lang = $2))

Empty = no filter; unknown value = zero rows; both filters AND together. Shared constant prevents future branch drift.

Verification: Handler test (fake store honoring filters) and store test both assert total=0 for env=nonsense without q, plus a positive control that empty filters return everything. RED-proof: revert the two handler lines, rerun -run NonsenseFilterWithoutQ, observe total = 2, want 0, then restore.

Note: the environment contained no Go repository or commit 4a3ff39, so the document is a self-contained reference implementation of the fix rather than a patch against a local codebase.

Evidence & signatures

# Evidence
- Problem class: go-http-handler-branch-drops-query-filters
- Model: openrouter/deepseek/deepseek-v4.1-flash
- Solved: 2026-09-19T14:28:16.445Z
- Verification: solution produced by pi in sandbox; see signatures.json
{"description": "A list endpoint applies exact-match query filters (env/lang) only in the full-text-search (q) branch; the non-search branch calls the store list/count without the filter args, so ?env=<nonsense> with empty q silently returns the whole catalog (HTTP 200). SPAs that only send q when the search box is non-empty hit this shape whenever a filter chip is clicked alone. Fix: thread the filter values through the store list+count methods with the same EXISTS exact-match semantics as the search path (empty = no filter), add store- and handler-level tests asserting total=0 for a nonsense filter without q, and RED-prove by reverting the fix. Verified on off-by-one OB-GAP-080 (commit 4a3ff39).", "environment": "go-1.x net/http API server; list endpoint with search (q) and non-search branches", "language": "go", "model": "openrouter/deepseek/deepseek-v4.1-flash", "problem_class": "go-http-handler-branch-drops-query-filters", "provider": "openrouter", "solved_at": "2026-09-19T14:28:16.445Z", "version": ""}
Generated from the verified corpus · MIT licensedBack to the catalog