Skip to content

Normalize hyphens in indexer queries and guard empty queries (relates to #1068) - #1070

Merged
therobbiedavis merged 4 commits into
Listenarrs:canaryfrom
dny238:fix/indexer-query-hyphen
Oct 22, 2026
Merged

therobbiedavis merged 4 commits into
Listenarrs:canaryfrom
dny238:fix/indexer-query-hyphen

Conversation

@dny238

@dny238 dny238 commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Relates to #1068. Two small, independent search-query changes.

1. Empty-query guard (safety)

A query that sanitizes to an empty string — dash-only or punctuation-only input — must never be dispatched: some indexers treat an empty query as "browse everything" and would return unrelated releases that could then be grabbed. IndexerSearchWorkflow now fails closed on an empty sanitized query (logs and returns no results without calling the provider). Covered by IndexerSearchWorkflowEmptyQueryTests (dash-only, collapsing-dash, punctuation-only, whitespace-only all assert the provider is never called and nothing is returned).

2. Hyphen/dash normalization (Prowlarr/Sonarr-style cleaning)

Hyphens and the Unicode dash variants are normalized to spaces, so a hyphenated title token like Full-Cast is searched as separate words (Full Cast) — consistent with how Prowlarr/Sonarr clean query terms, and defensive against any indexer or proxy that interprets a leading - as an operator. Covered by IndexerQuerySanitizerTests.

Note on #1068's root cause

I ran a read-only comparison against NZBgeek's API. De-hyphenating did not change which releases match — hyphen and space queries returned identical counts in every pair, and a direct -token probe did not exclude. The 0-result reports in #1068 track query specificity and the appended author instead: …Full Cast Edition returned results, but appending J.K. Rowling dropped it to 0 (release names don't carry the author), and adding more title words AND-matched to nothing.

So this PR is a normalization + safety change rather than the fix for #1068's symptom. The actual fix — a title-only / drop-the-author fallback when a query returns nothing — is a sensible follow-up (and matches the reporter's own suggestion). Keeping this open as relates to rather than fixes so #1068 stays open for that work. (Caveat: the report's path is via Prowlarr, which I bypassed by hitting NZBgeek directly, so Prowlarr-side - handling isn't ruled out — but against the indexer's own API the hyphen change is a no-op.)

🤖 Generated with Claude Code

@dny238
dny238 requested a review from a team October 20, 2026 15:45
@therobbiedavis therobbiedavis added the patch patch version bump - backward compatible bug fixes label Oct 20, 2026

@therobbiedavis therobbiedavis left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dny238 Looks good, just a couple things I'd like you to add to tighten up this PR.

I’d still check the split query against NZBgeek/Prowlarr with a hyphenated title, author and ISBN. The container checks verified the outgoing requests and download handling, but the fixtures returned results regardless of the query, so they don’t tell us whether splitting the words changes which releases match.

I’d also handle queries that become empty after sanitization here, with a negative test confirming they can’t trigger an unrelated download.

@therobbiedavis therobbiedavis left a comment •

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops forgot to leave it as a code review

The two inline comments are in my earlier review.

dny238 added a commit to dny238/Listenarr that referenced this pull request Oct 20, 2026
Addresses the review on Listenarrs#1070: a dash-only or punctuation-only query
sanitizes to an empty string, and some indexers treat an empty query as
"browse everything" — which could return unrelated releases that then get
grabbed. IndexerSearchWorkflow now fails closed when the sanitized query is
empty: it logs and returns no results without calling the provider.

Adds IndexerSearchWorkflowEmptyQueryTests asserting that dash-only,
collapsing-dash, punctuation-only and whitespace-only queries never invoke
the provider and return nothing (so nothing can be submitted).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@dny238

dny238 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — addressed both.

Empty-after-sanitization guard: IndexerSearchWorkflow.SearchIndexerAsync now fails closed when the sanitized query is empty — it logs and returns no results without calling the provider, so a dash- or punctuation-only query can't trigger a browse-everything grab. Added IndexerSearchWorkflowEmptyQueryTests: dash-only, collapsing-dash, punctuation-only and whitespace-only queries all assert the provider is never called and nothing is returned (the mock provider returns an unrelated release that must never surface).

Indexer comparison / ISBN: I can't drive a live NZBgeek/Prowlarr from here, so I can't add an assertion that the split query returns the same releases. A couple of things that bound the risk, though:

  • The indexer free-text query is title + author only. ISBNs don't reach this sanitizer — they're used in the Audible metadata path (AudibleAuthorSearchWorkflow.FilterByIsbnAsync), matched against the exact ISBN string, so hyphen-splitting here doesn't touch ISBN matching.
  • Space-separation (rather than removal) matches how Prowlarr/Sonarr normalize hyphens, and the reported symptom is exactly the -Cast exclusion this removes — Full Cast is what returned the releases in the issue's own manual tests.

If your container harness can vary fixtures by query, a title/author comparison there would be the definitive check; I just can't reproduce a live indexer in this environment. Happy to adjust if you'd prefer a different handling for any specific token.

@dny238 dny238 changed the title Fix: hyphenated titles return 0 results (hyphen read as Newznab exclusion) (#1068) Normalize hyphens in indexer queries and guard empty queries (relates to #1068) Oct 20, 2026
@dny238

dny238 commented Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

Ran the indexer comparison you asked for — read-only against NZBgeek's API — and it changed my read of this PR, so I've reframed it (and updated the title/description).

De-hyphenating made no difference. Every hyphen-vs-space pair returned identical counts:

query hyphen space
…Stone Full-Cast Edition 5 5
…Philosophers Stone Full-Cast (reporter's string) 0 0
Harry Potter Full-Cast 16 16

And a direct probe — Harry Potter Cast = 16 vs Harry Potter -Cast = 16 — shows NZBgeek's API isn't treating -token as an exclusion. So the "Newznab exclusion" premise doesn't hold against the indexer directly, exactly as you suspected.

What actually drives the 0 results: the appended author and query specificity. …Full Cast Edition returned 5, but adding J.K. Rowling → 0 (release names don't carry the author); and Harry Potter Full Cast = 16 while Harry Potter Philosophers Stone Full Cast = 0 (the AND of all those words matches nothing).

So I've demoted the hyphen change to Prowlarr/Sonarr-style query normalization (no exclusion claim) and kept it as relates to #1068 rather than fixes. The empty-query guard stands on its own. The real fix is the title-only / drop-the-author fallback you mentioned — I'd like to do that as a follow-up on #1068.

Caveat: the report's path is via Prowlarr and I hit NZBgeek directly, so I can't rule out Prowlarr-side - handling — but against the indexer's own API this is a no-op, so I didn't want to claim it fixes the symptom.

@therobbiedavis therobbiedavis left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to merge. The empty-query guard is verified, and the real indexer comparisons showed no lost matches from splitting hyphens in the tested titles and author.

The updated description also reflects what we found: this is a normalization and safety change. #1068 stays open for the title-plus-author search problem, with the fallback work tracked in #825.

@therobbiedavis

Copy link
Copy Markdown
Collaborator

@dny238 Please fix the test failures.

@dny238

dny238 commented Oct 21, 2026

Copy link
Copy Markdown
Contributor Author

Fixed — the unit-tests failure was format:backend:check (dotnet format --verify-no-changes) tripping on IDE0005 unused-using directives in the two new test files, not a failing test. Removed the redundant usings (the types resolve through the test project's global usings); format:backend:check now passes clean and the 17 tests across both classes are green. Pushed as 289591c.

dny238 and others added 4 commits October 21, 2026 23:51
Fixes Listenarrs#1068: searches for titles with a hyphenated word (e.g. "Full-Cast")
returned 0 results. IndexerQuerySanitizer dropped the usual operator
characters but passed hyphens through unchanged, and Newznab-style indexers
read a leading '-' on a token as an exclusion operator — so "Full-Cast" was
sent as "-Cast" and excluded exactly the releases we wanted.

Hyphens and the Unicode dash variants are now replaced with a space, so
"Full-Cast" becomes "Full Cast" (dropping the hyphen would wrongly join to
"FullCast"). Adds IndexerQuerySanitizerTests covering hyphens, dashes,
leading hyphens, stacked hyphens, and the existing operator/whitespace rules.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Addresses the review on Listenarrs#1070: a dash-only or punctuation-only query
sanitizes to an empty string, and some indexers treat an empty query as
"browse everything" — which could return unrelated releases that then get
grabbed. IndexerSearchWorkflow now fails closed when the sanitized query is
empty: it logs and returns no results without calling the provider.

Adds IndexerSearchWorkflowEmptyQueryTests asserting that dash-only,
collapsing-dash, punctuation-only and whitespace-only queries never invoke
the provider and return nothing (so nothing can be submitted).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
A direct read-only comparison against NZBgeek's API showed that de-hyphenating
does not change which releases match (hyphen and space queries returned
identical counts, and a direct "-token" probe did not exclude). So this is a
query-normalization change — hyphens become spaces, consistent with how
Prowlarr/Sonarr clean search terms and defensive against any proxy/indexer that
interprets a leading '-' — rather than the root-cause fix for the 0-result
reports in Listenarrs#1068, which are driven by query specificity and the appended
author (a title-only / author fallback is the follow-up). Comments updated to
drop the incorrect "Newznab exclusion" claim; the empty-query guard stands on
its own.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The CI format:backend:check (dotnet format --verify-no-changes) fails on
IDE0005 unused-using directives in the two new test files. Remove them;
the referenced types come in via the test project's global usings.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@therobbiedavis
therobbiedavis force-pushed the fix/indexer-query-hyphen branch from 289591c to a1cf66d Compare October 22, 2026 03:51
@therobbiedavis
therobbiedavis merged commit 9aba801 into Listenarrs:canary Oct 22, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch patch version bump - backward compatible bug fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants