Package: cocoindex-code v0.2.39 (installed via pipx)
Summary
Any ccc search invocation that includes --path crashes the daemon with a TypeError surfaced as a RuntimeError: Daemon error: .... --lang alone works fine; adding --path (with or without --lang) reliably reproduces the crash.
Steps to reproduce
ccc search --lang python --path 'src/*' "example query text"
Observed error
RuntimeError: Daemon error: unsupported operand type(s) for *: 'NoneType' and 'NoneType'
Full traceback points through cli.py:675 → cli.py:284 (_search_with_wait_spinner) → client.py:422 (search), which just re-raises whatever error message the daemon sent back.
Root cause
In cocoindex_code/query.py, query_codebase() dispatches to _full_scan_query() whenever paths is provided:
def _full_scan_query(conn, embedding_bytes, limit, offset, languages=None, paths=None):
...
return conn.execute(
f"""
SELECT file_path, language, content, start_line, end_line,
vec_distance_L2(embedding, ?) as distance
FROM code_chunks_vec
{where}
ORDER BY distance
LIMIT ? OFFSET ?
""",
params,
).fetchall()
This reads the embedding column directly from the code_chunks_vec vec0 virtual table in a full scan combined with a WHERE clause (language/path filters), rather than using the MATCH ... k = ? KNN access pattern that _knn_query() uses. In this access pattern, vec_distance_L2(embedding, ?) returns NULL for every row (verified by running the exact SQL by hand against the generated target_sqlite.db — the raw embedding column reads fine in isolation, but vec_distance_L2 returns None once combined with the WHERE filter in this scan shape).
That None distance then flows into:
def _l2_to_score(distance: float) -> float:
return 1.0 - distance * distance / 2.0
None * None → the exact crash observed.
Expected behavior
ccc search --path '' should return path-filtered results, same as it does for --lang.
Actual behavior
Any use of --path crashes the daemon, regardless of query content or --lang combination.
Suggested fix direction
vec0 virtual tables generally only support reliable distance computation through the MATCH KNN query path, not through direct scalar-function calls against the raw column in an arbitrary full scan. _full_scan_query likely needs to either compute embeddings/distance outside the vec0 table (e.g., store/query embeddings via a shadow table it can full-scan safely), or restructure the path-filtered query to still go through a MATCH-based KNN query and post-filter by path in Python.
Note: Bug explored, reproduced and reported by Claude code
Package: cocoindex-code v0.2.39 (installed via pipx)
Summary
Any ccc search invocation that includes --path crashes the daemon with a TypeError surfaced as a RuntimeError: Daemon error: .... --lang alone works fine; adding --path (with or without --lang) reliably reproduces the crash.
Steps to reproduce
ccc search --lang python --path 'src/*' "example query text"
Observed error
RuntimeError: Daemon error: unsupported operand type(s) for *: 'NoneType' and 'NoneType'
Full traceback points through cli.py:675 → cli.py:284 (_search_with_wait_spinner) → client.py:422 (search), which just re-raises whatever error message the daemon sent back.
Root cause
In cocoindex_code/query.py, query_codebase() dispatches to _full_scan_query() whenever paths is provided:
def _full_scan_query(conn, embedding_bytes, limit, offset, languages=None, paths=None):
...
return conn.execute(
f"""
SELECT file_path, language, content, start_line, end_line,
vec_distance_L2(embedding, ?) as distance
FROM code_chunks_vec
{where}
ORDER BY distance
LIMIT ? OFFSET ?
""",
params,
).fetchall()
This reads the embedding column directly from the code_chunks_vec vec0 virtual table in a full scan combined with a WHERE clause (language/path filters), rather than using the MATCH ... k = ? KNN access pattern that _knn_query() uses. In this access pattern, vec_distance_L2(embedding, ?) returns NULL for every row (verified by running the exact SQL by hand against the generated target_sqlite.db — the raw embedding column reads fine in isolation, but vec_distance_L2 returns None once combined with the WHERE filter in this scan shape).
That None distance then flows into:
def _l2_to_score(distance: float) -> float:
return 1.0 - distance * distance / 2.0
None * None → the exact crash observed.
Expected behavior
ccc search --path '' should return path-filtered results, same as it does for --lang.
Actual behavior
Any use of --path crashes the daemon, regardless of query content or --lang combination.
Suggested fix direction
vec0 virtual tables generally only support reliable distance computation through the MATCH KNN query path, not through direct scalar-function calls against the raw column in an arbitrary full scan. _full_scan_query likely needs to either compute embeddings/distance outside the vec0 table (e.g., store/query embeddings via a shadow table it can full-scan safely), or restructure the path-filtered query to still go through a MATCH-based KNN query and post-filter by path in Python.
Note: Bug explored, reproduced and reported by Claude code