/app/search?q=maes showed "Record search failed. Try again." plus a "Something went wrong" toast. POST /qqq/v1/search returned 200, 846 bytes (Traefik access log), and the backend logged nothing.
Root cause: two matching page_section records have an empty name, so their record label is "". QQQ serializes JSON with NON_EMPTY and leaves recordLabel out. RecordSearchResponseSchema required recordLabel on every result, so one such result rejected the whole response.
Fix
RecordSearchResultSchema: tableName and recordId are required (non-empty); recordId may be a number (converted to a string). tableLabel and recordLabel may be missing, null or empty.
searchRecords checks the { results: [] } envelope strictly, then validates each result on its own:
A result without a label is labeled "{table label} {record id}".
A result that can't link to a record is skipped with console.warn, and the other results still render.
The RecordSearchResult type and the hook/page contract are unchanged, so this is safe to build the search UX redesign on.
Server side: QRun-IO/qqq#1068 never emits a blank label and logs every search (outcome, provider, timing).
Tests
schemas.test: missing/null/empty labels accepted; numeric recordId accepted; empty tableName/recordId rejected; the envelope no longer fails on one bad result.
tables.test: the prod "maes" response shape now resolves with fallback labels; a malformed result is skipped with a warning.
The 5 new tests fail on RC.13 code and pass here. vitest (api, layout, hooks): 415 passed. tsc clean.
## Problem (prod, admin.kof22.com, 2026-10-12)
`/app/search?q=maes` showed **"Record search failed. Try again."** plus a "Something went wrong" toast. `POST /qqq/v1/search` returned **200, 846 bytes** (Traefik access log), and the backend logged nothing.
Root cause: two matching `page_section` records have an empty name, so their record label is `""`. QQQ serializes JSON with `NON_EMPTY` and leaves `recordLabel` out. `RecordSearchResponseSchema` required `recordLabel` on every result, so one such result rejected the whole response.
## Fix
- `RecordSearchResultSchema`: `tableName` and `recordId` are required (non-empty); `recordId` may be a number (converted to a string). `tableLabel` and `recordLabel` may be missing, null or empty.
- `searchRecords` checks the `{ results: [] }` envelope strictly, then validates each result on its own:
- A result without a label is labeled `"{table label} {record id}"`.
- A result that can't link to a record is skipped with `console.warn`, and the other results still render.
- The `RecordSearchResult` type and the hook/page contract are unchanged, so this is safe to build the search UX redesign on.
Server side: QRun-IO/qqq#1068 never emits a blank label and logs every search (outcome, provider, timing).
## Tests
- schemas.test: missing/null/empty labels accepted; numeric recordId accepted; empty tableName/recordId rejected; the envelope no longer fails on one bad result.
- tables.test: the prod "maes" response shape now resolves with fallback labels; a malformed result is skipped with a warning.
- The 5 new tests fail on RC.13 code and pass here. `vitest` (api, layout, hooks): 415 passed. `tsc` clean.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Merged on the owner's explicit approval ("Merge #57 despite NAV-056") with one known pre-existing failure: acceptance (webkit) NAV-056, which also fails on main since #53 and is tracked separately (qqq#985 comment 6122410722). All other checks green. Fixes production global search failing on blank record labels.
Merged on the owner's explicit approval ("Merge #57 despite NAV-056") with one known pre-existing failure: acceptance (webkit) NAV-056, which also fails on `main` since #53 and is tracked separately (qqq#985 comment 6122410722). All other checks green. Fixes production global search failing on blank record labels.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem (prod, admin.kof22.com, 2026-10-12)
/app/search?q=maesshowed "Record search failed. Try again." plus a "Something went wrong" toast.POST /qqq/v1/searchreturned 200, 846 bytes (Traefik access log), and the backend logged nothing.Root cause: two matching
page_sectionrecords have an empty name, so their record label is"". QQQ serializes JSON withNON_EMPTYand leavesrecordLabelout.RecordSearchResponseSchemarequiredrecordLabelon every result, so one such result rejected the whole response.Fix
RecordSearchResultSchema:tableNameandrecordIdare required (non-empty);recordIdmay be a number (converted to a string).tableLabelandrecordLabelmay be missing, null or empty.searchRecordschecks the{ results: [] }envelope strictly, then validates each result on its own:"{table label} {record id}".console.warn, and the other results still render.RecordSearchResulttype and the hook/page contract are unchanged, so this is safe to build the search UX redesign on.Server side: QRun-IO/qqq#1068 never emits a blank label and logs every search (outcome, provider, timing).
Tests
vitest(api, layout, hooks): 415 passed.tscclean.🤖 Generated with Claude Code
Merged on the owner's explicit approval ("Merge #57 despite NAV-056") with one known pre-existing failure: acceptance (webkit) NAV-056, which also fails on
mainsince #53 and is tracked separately (qqq#985 comment 6122410722). All other checks green. Fixes production global search failing on blank record labels.🤖 Generated with Claude Code