Repository navigation
claude-code-chat-browser: Distinct /api/search error codes and search UX polish #114
Description
Calendar Day
Tuesday, July 8, 2026
Planned Effort
Reduced from 5 to ~1–2 story points — most of the original 5 pt scope was shipped in Monday PR 2 (#121).
Depends on: Monday PR 1 (#120, feat/search-fts-index) and Monday PR 2 (#121, feat/search-errors-and-ux) merged to master.
Background — what Monday PRs already delivered
The original Tuesday spec (5 pt, item #2) called for error codes, API validation, search UI polish, docs, and tests. Monday PR 2 (#121, stacked on #120) shipped almost all of it:
Already done in PR #121
- Error codes added to
models/error_codes.py:SEARCH_EMPTY_QUERY,SEARCH_QUERY_TOO_LONG,SEARCH_INVALID_SINCE_DAYS,SEARCH_PROJECTS_UNAVAILABLE api/search.pyvalidation: emptyq→ 400, longq→ 400, invalidsince_days→ 400, projects dir inaccessible → 503, unexpected errors → 500 with no exception leakage- Search UI (
static/js/search.js): helper text (30-day window, result cap), "Search all history" checkbox (all_history=1), truncation warning,data-error-codeon error paragraph, empty-result vs error-state distinction, snippet term highlighting via<mark>afteresc() docs/api-reference.md: error catalog extended, per-route Errors table forGET /api/search, query param docs forall_historyandsince_days- Tests:
tests/test_search.pycovers each failure mode (empty query, long query, invalid since_days, projects unavailable, index lock fallback, tokenless query fallback),tests/test_error_propagation.pyno-leakage guard,tests/test_error_codes.pyparametrized, Vitest tests for structured errors, truncation, and all-history
NOT done — residual for this ticket
| Item | Detail |
|---|---|
SEARCH_INDEX_UNAVAILABLE error code |
Not added to ErrorCode enum — PR #121 handles index lock by falling back to live-scan or returning partial results, but never emits a named SEARCH_INDEX_UNAVAILABLE code |
Explicit 503 SEARCH_INDEX_UNAVAILABLE response |
When the index is locked and live-scan also fails (or no partial results exist), the API should return 503 with this code instead of silently degrading |
docs/api-reference.md entry for SEARCH_INDEX_UNAVAILABLE |
Missing from the catalog since the code doesn't exist yet |
Test for SEARCH_INDEX_UNAVAILABLE 503 |
tests/test_search.py needs a case where index is locked AND live-scan is unavailable → 503 |
Scope
1. Add SEARCH_INDEX_UNAVAILABLE to models/error_codes.py
SEARCH_INDEX_UNAVAILABLE = "SEARCH_INDEX_UNAVAILABLE"2. Wire 503 return in api/search.py
When _search_via_index detects index lock (index_locked flag) and has no partial results, and _search_live_scan also raises or returns no usable results, return:
error_response(ErrorCode.SEARCH_INDEX_UNAVAILABLE, "Search index is temporarily unavailable", 503)PR #121 already detects index_locked in _search_via_index — this adds the explicit 503 code on the path where fallback also fails.
3. Document in docs/api-reference.md
Add row to error catalog and per-route Errors table:
code |
HTTP | Routes | Meaning |
|---|---|---|---|
SEARCH_INDEX_UNAVAILABLE |
503 | GET /api/search |
FTS index is locked during rebuild and fallback is unavailable |
4. Test coverage
tests/test_search.py: index locked + live-scan raises → 503SEARCH_INDEX_UNAVAILABLEtests/test_error_codes.py: add parametrized case
Acceptance Criteria
-
SEARCH_INDEX_UNAVAILABLEmember inErrorCodeenum - Index locked + no fallback → 503
SEARCH_INDEX_UNAVAILABLE -
docs/api-reference.mdupdated -
tests/test_search.pycovers the 503 path -
mypy --strict,pytest,ruff,npm testpass - PR approved by at least 1 reviewer
Verification
cd C:\Users\Jasen\CppAliance\claude-code-chat-browser
.\.venv\Scripts\Activate.ps1
pytest tests/test_search.py tests/test_error_codes.py tests/test_error_propagation.py -q
pytest -q
mypy .
ruff check .Out of scope
Everything below was in the original Tuesday spec but is now shipped by Monday PRs #120 + #121:
- FTS index implementation (PR feat: FTS5 search index with background rebuild and 30-day default wi… #120)
SEARCH_EMPTY_QUERY,SEARCH_QUERY_TOO_LONG,SEARCH_INVALID_SINCE_DAYS,SEARCH_PROJECTS_UNAVAILABLE(PR Feat/search errors and ux #121)- Search UI helper text, all-history checkbox, truncation warning,
data-error-code, empty vs error distinction (PR Feat/search errors and ux #121) - Snippet term highlighting (PR Feat/search errors and ux #121)
docs/api-reference.mderror catalog for the four codes above (PR Feat/search errors and ux #121)tests/test_error_propagation.pyno-leakage guard (PR Feat/search errors and ux #121)- Vitest XSS test for highlighting (PR Feat/search errors and ux #121)
Activity