@@ -88,7 +88,7 @@ def json_dump_safe(value: object) -> str:
8888 """Best-effort JSON serialization for exclusion matching."""
8989 try :
9090 return json .dumps (value , ensure_ascii = False , sort_keys = True )
91- except Exception :
91+ except Exception : # noqa: BLE001 — best-effort fallback when value is not JSON-serializable
9292 return str (value ) if value is not None else ""
9393
9494
@@ -224,8 +224,16 @@ def _collect_ide_export_entries(
224224 )
225225 continue
226226
227+ if not isinstance (cd , dict ):
228+ _logger .debug (
229+ "Skipping corrupt composerData row %s: expected object, got %s" ,
230+ composer_id ,
231+ type (cd ).__name__ ,
232+ )
233+ continue
234+
227235 headers = cd .get ("fullConversationHeadersOnly" ) or []
228- if not headers :
236+ if not isinstance ( headers , list ) or not headers :
229237 continue
230238
231239 updated_at = to_epoch_ms (cd .get ("lastUpdatedAt" ))
@@ -270,7 +278,12 @@ def _collect_ide_export_entries(
270278 bubble_texts : list [str ] = []
271279 bubble_meta_parts : list [str ] = []
272280 for h in headers :
273- b = db_data .bubble_map .get (h .get ("bubbleId" ))
281+ if not isinstance (h , dict ):
282+ continue
283+ bubble_id = h .get ("bubbleId" )
284+ if not isinstance (bubble_id , str ):
285+ continue
286+ b = db_data .bubble_map .get (bubble_id )
274287 if not b :
275288 continue
276289 text = extract_text_from_bubble (b )
@@ -337,7 +350,7 @@ def _collect_cli_export_entries(
337350 exported : list [ExportEntry ] = []
338351 try :
339352 cli_projects = list_cli_projects (get_cli_chats_path ())
340- except Exception as e :
353+ except Exception as e : # noqa: BLE001 — log and skip CLI enumeration on any failure
341354 _logger .warning (
342355 "Could not enumerate CLI chats: %s (%s) — skipping" ,
343356 e ,
@@ -375,7 +388,7 @@ def _collect_cli_export_entries(
375388 try :
376389 messages = traverse_blobs (session ["db_path" ])
377390 bubbles = messages_to_bubbles (messages , created_ms )
378- except Exception as e :
391+ except Exception as e : # noqa: BLE001 — log and skip session on read/parse failure
379392 _logger .warning (
380393 "Could not read CLI session %s: %s (%s)" ,
381394 session_id ,
@@ -403,7 +416,7 @@ def _collect_cli_export_entries(
403416
404417 bubble_texts = [b ["text" ] for b in bubbles if b .get ("text" )]
405418 tool_call_texts = [
406- tc .get ("input" , "" ) or tc .get ("summary" , "" )
419+ json_dump_safe ( tc .get ("input" , "" ) or tc .get ("summary" , "" ) )
407420 for b in bubbles
408421 for tc in (b .get ("metadata" ) or {}).get ("toolCalls" ) or []
409422 ]
0 commit comments