You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
bug(graph): read-only Cypher validator rejects valid read queries that mention load, set, update or insert as identifiers #1511
utils/cypher_readonly.py:6-23, matched as \bKEYWORD\b at :58
The forbidden-keyword list mixes genuine Cypher write clauses with SQL statements Cypher does not have (INSERT, UPDATE, COPY, TRUNCATE, GRANT, REVOKE, ALTER) and with ordinary words that appear constantly as labels, property keys and aliases (LOAD, SET).
Because matching is \bKEYWORD\b over the whole query, any read query that merely mentions one is rejected:
$ .venv/bin/python -c "from codegraphcontext.utils.cypher_readonly import is_read_only_cypher as rfor q in ['MATCH (n:Module) RETURN n.load ORDER BY n.load', 'MATCH (n) WHERE n.update > 5 RETURN n', 'MATCH (n) RETURN n.name AS set', 'MATCH (n:Insert) RETURN count(n)']: print(f'allowed={r(q)} {q}')"allowed=False MATCH (n:Module) RETURN n.load ORDER BY n.loadallowed=False MATCH (n) WHERE n.update > 5 RETURN nallowed=False MATCH (n) RETURN n.name AS setallowed=False MATCH (n:Insert) RETURN count(n)
All four are read-only. n.load is a plausible property on a Module node; AS set is a plausible alias; Insert is a plausible class name in any codebase that models SQL.
Why it matters
execute_cypher_query is the documented expert fallback for agents that need something the typed tools don't cover. Rejecting valid reads pushes the agent into retry loops with no way to phrase the query that works, and the rejection message names keywords the user never wrote as a clause.
Suggested fix
Match write clauses by position rather than bare word presence — a keyword only starts a write when it appears where a clause can begin, not after a . (property access), not after AS (alias), and not as a label/rel-type. Dropping the SQL-only words (INSERT, UPDATE, TRUNCATE, GRANT, REVOKE) costs nothing, since Cypher has no such statements — though note COPY and ALTER are currently asserted in tests/unit/utils/test_cypher_readonly.py:13-14, so that test encodes the present policy and would need revisiting alongside.
Related: #1233 (audit logging for rejections) would make this class of false rejection visible.
Environment
Commit
c0e0bed (main)
Python
3.12.3, Linux
Reproduced with the snippet above. Distinct from the literal/comment-ordering bypass fixed in #1508.
Hi @Shashankss1205, I would like to work on this under GSSoC 2026 if it is available.
Proposed approach:
trace the read-only Cypher validation logic that currently rejects identifier text such as load, set, update, or insert
tighten the validator so it blocks actual write clauses/keywords while allowing those words when they appear as labels, properties, aliases, or identifiers in read-only queries
add focused regression tests for safe read queries using those identifiers plus negative tests for real write operations
I will wait for formal assignment before coding and keep the PR small, tested, and review-ready.
Activity
github-actions commentedon Aug 1, 2026
Hi! 👋 Join our CodeGraphContext Discord channel to collaborate: https://discord.gg/dR4QY32uYQ
mittalsonal commentedon Aug 10, 2026
Hi @Shashankss1205, I would like to work on this under GSSoC 2026 if it is available.
Proposed approach:
load,set,update, orinsertI will wait for formal assignment before coding and keep the PR small, tested, and review-ready.
fix: eight open issues across jobs, watcher, validator, simulator, MC…