From be2ee44bf046c3914efbc39edcddda8056bcd181 Mon Sep 17 00:00:00 2001 From: Jessica Mulein Date: Thu, 11 Jun 2026 08:57:19 -0700 Subject: [PATCH] fix(tools): sanitize ExploreCode queries for Cymbal FTS5 safety MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit py-cymbal's Cymbal CLI interprets hyphens in search queries as SQL FTS5 NOT operators, causing 'no such column' crashes when the model passes hyphenated terms like 'vault-store' or 'home-entry'. Sanitize all symbol queries by replacing hyphens with underscores before passing to Cymbal. This is semantically correct (code symbols use underscores, not hyphens) and prevents the crash regardless of which py-cymbal version is installed. The root cause is in py-cymbal's Go binary (unquoted FTS5 input) — a fix has been reported to the Cymbal team (dwash). This cecli-side workaround provides immediate defense. --- cecli/tools/explore_code.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/cecli/tools/explore_code.py b/cecli/tools/explore_code.py index 2f9d9621197..685189fadda 100644 --- a/cecli/tools/explore_code.py +++ b/cecli/tools/explore_code.py @@ -120,7 +120,10 @@ def execute(cls, coder, queries, **kwargs): try: if action == "search": - results = c.search(symbol, limit=limit) + # Sanitize symbol: Cymbal's CLI interprets hyphens as SQL operators. + # Replace hyphens with underscores (common in code) and strip special chars. + safe_symbol = symbol.replace("-", "_") if symbol else symbol + results = c.search(safe_symbol, limit=limit) all_results.append(cls._format_search_results(results, symbol)) elif action == "investigate": symbol_name = symbol @@ -131,8 +134,11 @@ def execute(cls, coder, queries, **kwargs): file_hint = parts[0] symbol_name = parts[1] + # Sanitize for Cymbal search + safe_name = symbol_name.replace("-", "_") if symbol_name else symbol_name + try: - investigation = c.investigate(symbol_name, file_hint) + investigation = c.investigate(safe_name, file_hint) all_results.append( cls._format_investigation_results(investigation, symbol) ) @@ -151,7 +157,8 @@ def execute(cls, coder, queries, **kwargs): else: raise e elif action == "find_references": - references = c.find_references(symbol, limit=limit) + safe_symbol = symbol.replace("-", "_") if symbol else symbol + references = c.find_references(safe_symbol, limit=limit) all_results.append(cls._format_reference_results(references, symbol)) else: all_failed_queries.append(