Skip to content

fix: keep tag search filter for hyphenated slugs - #1638

Open
breken-ai wants to merge 1 commit into
apache:devfrom
breken-ai:fix/search-tag-filter-hyphen
Open

breken-ai wants to merge 1 commit into
apache:devfrom
breken-ai:fix/search-tag-filter-hyphen

Conversation

@breken-ai

Copy link
Copy Markdown

Fixes: n/a (no existing issue; details below)

Proposed Changes

  • Bug: the documented [tag] search filter ("Advanced Search Tips": [tag] search with a tag) is silently ignored when the tag slug contains -, ., + or any other non-\w character. Searching [react-native] navigation returns matches from every tag instead of only react-native. When a question is created, spaces in a new tag name are saved as - (question_service.go), so every multi-word tag is affected, along with slugs like node.js and c++.
  • Cause: SearchDTO.Check → ReplaceSearchContent protects [tag] tokens from the special-character cleanup, but only matches \[\w+\]. A token like [react-native] doesn't match, so the cleanup regex turns it into [react native]. SearchParser.parseTags then looks up the slug react native, finds no tag, skips it, and still strips the bracket token. The query then runs with no tag condition at all.
  • Fix: the tag pattern in ReplaceSearchContent now accepts any non-space, non-bracket characters: \[[^\[\]\s]+\]. parseTags already matches \[(.*?)\], so no other change is needed.
  • Tests:
    • internal/schema/search_schema_test.go adds [react-native] [node.js] [c++] navigation-bar. On dev @ 6c00c788 this becomes [react native] [node js] [c ] navigation bar; with the fix the tags stay intact.
    • internal/repo/repo_test/search_tag_filter_test.go (new, ASF header) is an end-to-end test on the SQLite repo test DB. It creates tags search-hyphen-tag and search.dot.tag and two matching questions, only one of them tagged. It then runs the same path as GET /answer/api/v1/search: SearchDTO.Check → SearchParser.ParseStructure (real TagCommonService) → searchRepo.SearchContents. On dev it fails with tag filter dropped, query became "[search hyphen tag] tagfilter". With the fix, only the tagged question is returned.
  • Checks: go test ./internal/schema/ ./internal/repo/... ./internal/service/... passes, and go vet, gofmt and golangci-lint v2.6.2 report 0 issues.

This bug was found and the fix and tests were written with AI assistance (Claude); I reviewed the change and ran the tests above.

SearchDTO.Check only preserved [tag] tokens made of \w characters and
then replaced "-", ".", "+" and friends with spaces. A search for
[react-native] reached the parser as [react native], no tag has that
slug, so the tag filter was silently dropped and results came from
every tag. New tags with spaces are saved with "-", so this hits any
multi-word tag. Accept any non-space, non-bracket characters inside
the brackets.

Generated-by: Claude Opus 5.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@LinkinStars
LinkinStars self-requested a review October 14, 2026 11:04
@LinkinStars LinkinStars self-assigned this Oct 14, 2026
@LinkinStars LinkinStars added this to the v2.0.4 milestone Oct 14, 2026
@LinkinStars

Copy link
Copy Markdown
Member

Thanks for identifying and covering the hyphen/dot/plus slug case. There is one parsing conflict that should be addressed before merging.

The new pattern accepts any non-whitespace, non-bracket character inside [tag], including :. Tag slugs currently have no backend character validation beyond length, and the UI character restriction is commented out, so slugs such as score:3 or user:me can exist.

However, ReplaceSearchContent extracts key:value tokens before it extracts [tag] tokens. For example, with:

[score:3] database

keyValueRegex also matches score:3] inside the brackets. The reconstructed query therefore contains both a tag token and a score filter token. Later, parseTags resolves [score:3], while parseVotes also sees score:3 and applies an unintended score filter. The remaining bracket characters can also end up in the search words.

The same issue applies to [user:me], [answers:0], [is:question], and the other documented advanced-search prefixes.

Could we first extract and remove complete [tag] tokens, then run the key:value extraction only on the remaining text? Please also add regression tests for at least [score:3] and [user:me] to verify that a tag slug does not activate the corresponding advanced-search filter. This would preserve the intended fix for react-native, node.js, and c++ without making the search syntaxes ambiguous.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants