Skip to content

fix(extract): return empty + selector_no_match when a selector matches nothing#292

Merged
us merged 2 commits into
us:mainfrom
paoloantinori:fix/selector-no-match-empty-warning
Jul 15, 2026
Merged

fix(extract): return empty + selector_no_match when a selector matches nothing#292
us merged 2 commits into
us:mainfrom
paoloantinori:fix/selector-no-match-empty-warning

Conversation

@paoloantinori

Copy link
Copy Markdown
Contributor

What

Fixes #291.

When a user-supplied content selector matches no elements, crw now returns empty content and adds selector_no_match to metadata.warnings, instead of silently returning the entire page.

Applies to all three selector inputs:

  • includeTags (MCP crw_scrape / REST /v1/scrape)
  • --css (CLI)
  • --xpath (CLI)

Why

An unmatched selector falling back to the whole page is a footgun for the LLM-agent use case: the output looks normal so it gets trusted, but the full document is dumped into the model's context. I hit this directly when it exhausted an agent's context window mid-session. Repro and root cause in #291.

Changes

  • crates/crw-extract/src/clean.rs
    • keep_only_selectors: on no match, push selector_no_match and return an empty string instead of the whole html.
    • Non-breaking split: clean_html keeps its 4-arg signature (discards warnings) via clean_html_impl; new clean_html_with_warnings surfaces the warning.
  • crates/crw-extract/src/lib.rs
    • extract() uses clean_html_with_warnings at the two production call sites that carry include_tags.
    • CSS/XPath no-match: when user_selected and apply_selector returns None, push selector_no_match and use empty content instead of falling back to the whole cleaned page. Domain-configured default selectors are excluded (a host default that doesn't apply still shows the page).

Behavior change to flag

include_tags with an invalid selector (parse error) previously fell back to the whole page too; it now yields empty + selector_no_match, consistent with the valid-but-no-match case. The existing clean_html_invalid_css_selector test was updated to reflect this.

Testing

cargo test -p crw-extract → 173 lib + 17 clean_tests + 11 extract_tests, all green. Added include_tags_no_match_returns_empty_and_warns; updated clean_html_invalid_css_selector.

clean_html's public signature is unchanged, so other crates (e.g. crw-server security tests that call clean_html) compile without modification.

paoloantinori and others added 2 commits July 15, 2026 21:18
…s nothing

includeTags (MCP/REST) and --css/--xpath (CLI) previously fell back to the entire page when the selector matched no elements, silently dumping the full document into the output — a footgun for LLM agents whose context fills up (observed in practice).

Now an unmatched user-supplied selector yields empty content and pushes a 'selector_no_match' warning into metadata.warnings. Domain-configured default selectors are excluded (a host default that does not apply should still show the page). clean_html's public signature is unchanged; a new clean_html_with_warnings surfaces the warning and is used by the extract pipeline.

Changes: clean_html_with_warnings/clean_html_impl split (non-breaking); keep_only_selectors returns empty + warning instead of whole page; extract() css/xpath no-match (user_selected) -> Some(empty) + warning; tests add a no-match case and update the invalid-selector test.
…nclude_tags

An unmatched includeTags selector emptied the cleaned HTML, but the pipeline
then re-injected the page title and meta description and re-ran the alternates
ladder, so callers still received page content plus a duplicated
selector_no_match warning. Treat an unmatched include_tags as an intentional
empty narrowing: it now takes precedence over any trailing css/xpath selector
(an xpath scalar like count(//x) no longer leaks "0"), skips title and
description enrichment, and warns exactly once. Adds full-pipeline regression
tests for the include_tags, css, both, and xpath-scalar no-match cases.
@us us merged commit 819372d into us:main Jul 15, 2026
9 checks passed
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.

includeTags / --css / --xpath matching nothing returns the whole page instead of empty + warning

2 participants