@@ -272,23 +272,26 @@ def search_page(self, query_text: str, page: int) -> dict[str, Any]:
272272 return payload
273273
274274 def collect_query (self , query_text : str , first : dict [str , Any ]) -> list [dict [str , Any ]]:
275- total = int (first .get ("total_count" , 0 ))
276- if total > 1000 :
275+ initial_total = int (first .get ("total_count" , 0 ))
276+ if initial_total > 1000 :
277277 raise SyncError (f"search shard still exceeds 1,000 repositories: { query_text } " )
278- repositories = list (first .get ("items" , []))
279- page = 2
280- while len (repositories ) < total :
281- payload = self .search_page (query_text , page )
282- items = payload .get ("items" , [])
283- if not items :
284- break
285- repositories .extend (items )
286- page += 1
287- if len (repositories ) != total :
288- raise SyncError (
289- f"search shard reported { total } repositories but returned { len (repositories )} "
290- )
291- return repositories
278+ seen : dict [int , dict [str , Any ]] = {}
279+ next_first = first
280+ for _ in range (3 ):
281+ latest_total = int (next_first .get ("total_count" , 0 ))
282+ page = 1
283+ while page <= max (1 , (latest_total + 99 ) // 100 ):
284+ payload = next_first if page == 1 else self .search_page (query_text , page )
285+ latest_total = int (payload .get ("total_count" , latest_total ))
286+ for item in payload .get ("items" , []):
287+ seen [int (item ["id" ])] = item
288+ page += 1
289+ if len (seen ) >= latest_total :
290+ return list (seen .values ())
291+ next_first = self .search_page (query_text , 1 )
292+ raise SyncError (
293+ f"search shard did not converge: latest={ latest_total } , unique={ len (seen )} "
294+ )
292295
293296 def collect_date_range (
294297 self ,
0 commit comments