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
{{ message }}
Repository navigation
semantic_search: truncation warning misses SMW's server-side result cap #162
That catches truncation at the requested limit only. SMW also caps every request server-side at $smwgQMaxLimit (default 10000, https://www.semantic-mediawiki.org/wiki/Help:$smwgQMaxLimit). A request above the cap is silently reduced, so a query asking for 50000 and truncated at the wiki's 10000 returns 10000 results, 10000 >= 50000 is false, and no warning is emitted. The caller sees a short result set with nothing to indicate it is incomplete.
The same applies to $smwgQUpperbound for the printout limit.
Possible approach
$smwgQMaxLimit is not exposed through siteinfo. Options, in rough order of preference:
Ask for limit + 1 and warn when more than limit come back. Robust and needs no server config, but changes what is sent and costs one extra result per query.
Read SMW's own truncation signal: an ask response carries query.meta.count and query.meta.offset, and SMW sets query.meta.hasFurtherResults when more results exist beyond the returned set. Warning on hasFurtherResults would cover both the requested limit and the server cap, and would replace the count comparison entirely.
The third looks like the right fix: it asks SMW whether the result set is complete instead of inferring it.
Context
Noticed while reviewing #161, which fixes the related case where a caller-supplied |limit= in the query string was silently overridden. The warning itself was added in #150.
The same gap exists in the service layer added by PR #133
#133 adds osw.service.ops.search, whose search operations return a truncated field to CLI and MCP callers. Commit 5c26a76 makes that field fire when the result count reaches the limit that reached the wiki:
"""Whether a result set is as large as the limit that produced it.
The wiki applies the limit itself, so ``cap_list`` never has to cut these
results and its own flag stays False. A full result set is then the only
signal left that the wiki may hold further matches. ``limit=0`` asks for
no results, so meeting it says nothing about truncation.
"""
returnbool(limit) andtotal>=limit
That mirrors the if limit and n >= limit condition in semantic_search, so it inherits exactly the blind spot this issue describes. A server-side cap below the requested limit returns fewer rows than asked for, total >= limit is false, and truncated reads False for a result set that was cut.
The service layer widens the gap to two more APIs:
Operation
API
Server cap
search_entities, list_instances_of_category
SMW ask
$smwgQMaxLimit
search_titles
MediaWiki prefixsearch
pslimit maximum
search_content
MediaWiki search
srlimit maximum
At the default OSW_MAX_RESULTS of 100 none of these caps is reached. A caller passing a larger limit can reach all three.
What this means for the proposed fix
Reading query.meta.hasFurtherResults, the third option above, would fix the service layer too, but only if semantic_search returns the signal instead of only warning about it. search_entities calls it with the default return_json=False and receives a flat list of titles:
So the signal is not reachable from there today. Whichever option is chosen, returning the truncation state from semantic_search rather than only emitting a warning would let callers report it instead of re-deriving it from the result count.
hasFurtherResults appears nowhere in the response, neither under query nor under query.meta, whose keys are hash, count, offset, source and time. So option 3 as written is not implementable, but its idea is: the wiki does report completeness, under a different key and one level higher. query.meta in the issue text is the right path for count and offset.
The count comparison also invents truncation
Checking the case the issue does not mention, a complete result set whose size equals the limit. [[Has type::Date]] has 18 results in total:
query
count returned
query-continue-offset
[[Has type::Date]]|limit=18
18
absent
[[Has type::Date]]|limit=17
17
17
18 >= 18 is true, so the old check warns about a result set that is complete. That is not a rare shape: at the OSW_MAX_RESULTS default of 100, any category with exactly 100 instances would set truncated wrongly in osw.service.ops.search.
Since the offset is present exactly when the set was cut short, it replaces the count comparison rather than supplementing it. Keeping the count as a fallback would only re-add the false positive.
A limit=0 count query returns no offset even when the query matches pages, so it stays silent as before.
Fix
#171 changes semantic_search in wiki_tools on main:
truncation is read from query-continue-offset
SearchParam.return_meta=True returns one SemanticSearchResult per query, with query, titles, count, truncated and next_offset, so a caller can report the state instead of re-deriving it
the return_json=True path is unchanged, since the raw response it returns already carries the offset
Wiring osw.service.ops.search to return_meta stays with #133, since src/osw/service/ does not exist on main yet.
search_titles and search_content are not covered. They use prefixsearch and search, which report continuation differently, so they need separate handling in #133.
Activity
LukasGold commentedon Sep 7, 2026
The same gap exists in the service layer added by PR #133
#133 adds
osw.service.ops.search, whose search operations return atruncatedfield to CLI and MCP callers. Commit 5c26a76 makes that field fire when the result count reaches the limit that reached the wiki:osw-python/src/osw/service/ops/search.py
Lines 17 to 26 in bca9d1f
That mirrors the
if limit and n >= limitcondition insemantic_search, so it inherits exactly the blind spot this issue describes. A server-side cap below the requested limit returns fewer rows than asked for,total >= limitis false, andtruncatedreadsFalsefor a result set that was cut.The service layer widens the gap to two more APIs:
search_entities,list_instances_of_categoryask$smwgQMaxLimitsearch_titlesprefixsearchpslimitmaximumsearch_contentsearchsrlimitmaximumAt the default
OSW_MAX_RESULTSof 100 none of these caps is reached. A caller passing a largerlimitcan reach all three.What this means for the proposed fix
Reading
query.meta.hasFurtherResults, the third option above, would fix the service layer too, but only ifsemantic_searchreturns the signal instead of only warning about it.search_entitiescalls it with the defaultreturn_json=Falseand receives a flat list of titles:osw-python/src/osw/service/ops/search.py
Lines 64 to 79 in bca9d1f
So the signal is not reachable from there today. Whichever option is chosen, returning the truncation state from
semantic_searchrather than only emitting a warning would let callers report it instead of re-deriving it from the result count.LukasGold commentedon Sep 7, 2026
hasFurtherResultsdoes not exist,query-continue-offsetdoesMeasured with
mwclient, the client this library uses, against https://www.semantic-mediawiki.org.A truncated
askresponse carries a top-levelquery-continue-offsetholding the offset the remainder starts at. A complete one omits the key.hasFurtherResultsappears nowhere in the response, neither underquerynor underquery.meta, whose keys arehash,count,offset,sourceandtime. So option 3 as written is not implementable, but its idea is: the wiki does report completeness, under a different key and one level higher.query.metain the issue text is the right path forcountandoffset.The count comparison also invents truncation
Checking the case the issue does not mention, a complete result set whose size equals the limit.
[[Has type::Date]]has 18 results in total:query-continue-offset[[Has type::Date]]|limit=18[[Has type::Date]]|limit=1718 >= 18is true, so the old check warns about a result set that is complete. That is not a rare shape: at theOSW_MAX_RESULTSdefault of 100, any category with exactly 100 instances would settruncatedwrongly inosw.service.ops.search.Since the offset is present exactly when the set was cut short, it replaces the count comparison rather than supplementing it. Keeping the count as a fallback would only re-add the false positive.
A
limit=0count query returns no offset even when the query matches pages, so it stays silent as before.Fix
#171 changes
semantic_searchinwiki_toolson main:query-continue-offsetSearchParam.return_meta=Truereturns oneSemanticSearchResultper query, withquery,titles,count,truncatedandnext_offset, so a caller can report the state instead of re-deriving itreturn_json=Truepath is unchanged, since the raw response it returns already carries the offsetWiring
osw.service.ops.searchtoreturn_metastays with #133, sincesrc/osw/service/does not exist on main yet.search_titlesandsearch_contentare not covered. They useprefixsearchandsearch, which report continuation differently, so they need separate handling in #133.LukasGold commentedon Sep 18, 2026
Another confirmation of the false positive, measured on a second wiki
(
arkeve.isc.fraunhofer.de, 2026-09-17).The query
[[Category:OSWc5d4829ed2744a219ba027171c75fa1d]]matches 408 tasks.limitquery-continue-offsetwiki_toolswarnsThe
limit=408row is the false positive. The result set is complete and theserver sends no continuation offset, but the count check at
https://github.com/OpenSemanticLab/osw-python/blob/9aa6322/src/osw/wiki_tools.py#L394
still emits the
UserWarning:This repeats what was already measured against semanticmediawiki.org and shows
the behaviour is not instance specific.
A working implementation of the check now ships in this repository, in
_ask_rowsinsrc/osw/service/ops/tasks.pyon thefeat/mcp-serverbranch:It reads the top-level key and nothing else.
semantic_searchcan adopt thesame test.