You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Brave Search is a live external I/O boundary used directly and through Perplexica's SearXNG compatibility path. One null, scalar, or non-string field inside an otherwise valid upstream results array currently throws during .trim(), turning the whole search into a 500 and discarding valid sibling results.
Root cause and invariant
The proxy checked that web.results was an array but assumed every element was an object and every mapped field was a string. The invariant is that malformed individual upstream records cannot crash the service; only object records with a usable string URL become public results, while valid siblings retain their stable shapes.
The shared extractor now rejects non-object entries and a single string normalizer handles title, URL, and description in both response formats.
Overlap check
Searched open and closed PRs for brave search malformed upstream result, invalid upstream payload, and the changed files. Open same-production-file PR #2734 adds caller authentication to the native route and does not touch upstream result mapping. No semantic duplicate was found.
Regression coverage
The existing loopback end-to-end harness now makes the stub Brave server return null, scalar, wrong-typed fields, and one valid sibling. It exercises both real proxy child processes and asserts /v1/search plus SearXNG /search return 200 with exactly the valid normalized result.
Validation
bash ods/tests/test-brave-search-searxng-compat.sh ? all checks passed
Malformed entries are skipped rather than failing the whole response, matching the existing behavior for empty URLs and malformed top-level shapes. ODS does not invent values for invalid fields. Revert restores the per-item crash behavior; no configuration or data migration is required.
Validated merge order: #2989 ? #2990 ? #2993 ? #2991 ? #2992 ? #2994 ? #2995 ? #2996 ? #2997 ? #2998. The changes are independently useful; this order only reconciles shared model-router and magic-link files.
Synthetic integration head: origin/batch/quality-ten-20260822-round2-integration at 91eb730d. The only textual conflict was the two model-router tests inserting at the same class boundary; the integration resolution retains both contracts. Magic-link changes merged cleanly.
All required GitHub checks are green across the batch. #2992 initially hit a transient openSUSE repository/mirror failure while installing rsync; a clearly labeled empty retry commit reran the unchanged tree, and openSUSE plus the full matrix passed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why this matters
Brave Search is a live external I/O boundary used directly and through Perplexica's SearXNG compatibility path. One
null, scalar, or non-string field inside an otherwise valid upstream results array currently throws during.trim(), turning the whole search into a 500 and discarding valid sibling results.Root cause and invariant
The proxy checked that
web.resultswas an array but assumed every element was an object and every mapped field was a string. The invariant is that malformed individual upstream records cannot crash the service; only object records with a usable string URL become public results, while valid siblings retain their stable shapes.The shared extractor now rejects non-object entries and a single string normalizer handles title, URL, and description in both response formats.
Overlap check
Searched open and closed PRs for
brave search malformed upstream result,invalid upstream payload, and the changed files. Open same-production-file PR #2734 adds caller authentication to the native route and does not touch upstream result mapping. No semantic duplicate was found.Regression coverage
The existing loopback end-to-end harness now makes the stub Brave server return null, scalar, wrong-typed fields, and one valid sibling. It exercises both real proxy child processes and asserts
/v1/searchplus SearXNG/searchreturn 200 with exactly the valid normalized result.Validation
bash ods/tests/test-brave-search-searxng-compat.sh? all checks passednode --check ods/extensions/services/brave-search/proxy.mjsnode --check ods/tests/test-brave-search-searxng-compat.mjsgit diff --checkTradeoffs and rollback
Malformed entries are skipped rather than failing the whole response, matching the existing behavior for empty URLs and malformed top-level shapes. ODS does not invent values for invalid fields. Revert restores the per-item crash behavior; no configuration or data migration is required.