Skip to content

ccc search --path crashes the daemon: unsupported operand type(s) for *: 'NoneType' and 'NoneType' #270

Description

@jaimebelt

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions