Repository navigation
bug(indexer): A symlinked file inside a repo aborts the entire index run #1383
Description
tools/indexing/persistence/writer.py:248
file_path_obj = Path(file_path_str) # already .resolve()d — follows symlinks
repo_path_obj = Path(resolved_repo_str)
relative_path_to_file = file_path_obj.relative_to(repo_path_obj) # ← unguardedSeventeen lines earlier, at :230-233, the same operation is wrapped in try/except ValueError. add_minimal_file_node at :624 guards it too. This one call is bare.
_normalize_path calls .resolve(), which follows symlinks, so any symlink inside the repo pointing outside it makes relative_to raise. The exception unwinds through run_tree_sitter_index_async to build_graph_from_path_async, which marks the job FAILED and stops. Nothing after that file is written — no symbols, no CALLS, no inheritance. There is no transaction on FalkorDB/Kùzu (persistence/utils.py:29-31 returns a plain session), so nothing rolls back.
Reproduced. A repo with one real file plus sub/link.py → ../outside/target.py:
$ cgc index /home/claude/verify/scratch/c7
An error occurred during indexing: '/home/claude/verify/scratch/outside/target.py'
is not in the subpath of '/home/claude/verify/scratch/c7'
EXITCODE=0
Result: normal.py indexed, zzz_last.py never reached, zero Function nodes. Worse, a partial File node for /…/outside/target.py was left behind, and because its path sits outside the repo prefix, delete_repository_from_graph (which filters on path STARTS WITH repo + "/") cannot remove it — it survived both cgc delete and cgc delete --all and had to be deleted by hand.
Compounding it: cli_helpers.py:326-336 then refuses to re-index ("already indexed with N files. Skipping.") because file_count > 0, so the corrupted partial graph is sticky until the user discovers --force.
Fix. Wrap :248 in the same try/except ValueError used at :231, falling back to os.path.relpath. Additionally catch per-file exceptions in pipeline.py so one bad file cannot abort a run.
Related existing issues
- Named context "Repos Linked: 0" desync: index_helper early-return skips register_repo_in_context for already-populated graphs #1317 — the same "already indexed … Skipping" guard is what makes the corrupted partial graph sticky
Filed separately because the root cause and fix differ; close as a duplicate if maintainers judge otherwise.
Audit environment
| Version | codegraphcontext 0.5.2 (PyPI) |
| Commit | df3af04 |
| Backend | FalkorDB Lite (falkordblite 0.9.0), Python 3.12.3, Linux |
| Corpus | the CodeGraphContext repo itself — 784 files, 23 languages, 5,501 Function nodes |
Audit ID I-C1 · severity critical · from an end-to-end audit of CGC 0.5.2 (63 findings). Reported with the reproduction as run.
Metadata
Metadata
Assignees
Labels
Type
Projects
- StatusShow more project fieldsDone
- StatusShow more project fieldsNo status
Activity
github-actions commentedon Jul 26, 2026
Hi! 👋 Join our CodeGraphContext Discord channel to collaborate: https://discord.gg/dR4QY32uYQ