Repository navigation
10 Troubleshooting
Recovery recipes — each for a state that actually occurred or is described by the code. Pattern: diagnosis → action → verification. Normative source: docs/skills/ragraf-core/reference/repair.md.
| Symptom | Jump to |
|---|---|
Facts don't match the code / check loops |
§1 Stale or trembling index |
catalog shows zeros, status shows data |
§2 Empty registry |
slice refuses / capability=degraded
|
§3 Degraded |
| Files vanished from search after an exclusion edit | §4 Exclusions |
| Index has fewer files than disk | §5 Dedupe |
| Indexing slower than expected, CPU computer | §6 GPU fallback |
certificate verify failed on model download |
§7 TLS |
| Installer hangs / fails | §8 Installer |
ragraf not found after install |
§9 Entry points |
| Joern server eating RAM / holding port | §3, Important box |
Symptom. Operations answer but facts mismatch the code; freshness reports divergence; check reindexes on every call.
Diagnosis.
ragraf -p cfg check
ragraf -p cfg statuscheck compares the corpus checksum with the revision's. If sums match but stale doesn't clear — the problem is the revision record, not the files.
Action.
ragraf -p cfg reindexIf it loops: the checksum must be computed over exactly the files that land in the index, after duplicate collapsing (corpus.py:59-70, :242-253). If collapsing is moved into the indexer or the guard, the sum diverges from index contents and reindexing never stops. The doctrine checker (tools/Invoke-ProjectDoctrine.ps1) has a rule for exactly this invariant.
Symptom. catalog shows rev — none, nodes 0, edges 0, while status of the same corpus reports a live revision.
Status: fixed in the shipped code. Historical cause: ensure registered the corpus before indexing and never recorded the run result (measured: register trigger, zeros, 1855 nodes in the index). Now ensure calls record_index_run(..., trigger="ensure:index") after success (ensure.py:338-348).
If you still see zeros (old install, interrupted run):
ragraf -p cfg index # this path writes the registry (cli.py:247)
# or trigger the guard once — it records results itself (watch.py:554)
ragraf -p cfg checkVerification: catalog gains revision, counts, and a trigger like guard:fast / ensure:index.
Symptom. index_status reports degraded; slice refuses (exit 3).
Meaning. The CPG layer wasn't built or its export failed. Lexicon, vectors, parse graph, schema — all working. Silent degradation doesn't exist (cpg.py:9-11).
Diagnosis.
ragraf -p cfg status # the `cpg` stage holds the reasonAction.
- Verify Java + Joern are where the code looks:
RAGRAF_JOERN_HOME/RAGRAF_JAVA_HOME→.tools/joern-cli,.tools/jdk→ PATH (cpg.py:82-93,:391). For PHP corpora: aphp≥ 7.1 in PATH is mandatory (php2cpg shells out to it). - Re-run indexing — the layer rebuilds.
- If refusal repeats: work without slice operations and record the finding. Known unlocalized case: export exit 1 with «next on empty iterator» while
cpg.binwas built — a layer defect, not a config problem.
Important: the Joern server stops automatically when the indexer closes (
indexer.py:1166-1183). After manual experiments check the process list — a stray server is gigabytes of RAM holding port 9500.
Do not present degraded as «the index is broken».
Symptom. Files that were searchable disappeared; no errors anywhere.
Cause. Glob matching is case-sensitive and only **-tailed patterns prune directories: **/cache/** catches src/cache/ but not src/Cache/ (util.py:72-158). Defect E-01, roadmap R-CORE-1.
Action (portable procedure — the author's measurement tools are not shipped):
ragraf -p cfg status # file count BEFORE
# ...apply the exclusion change...
ragraf -p cfg check && ragraf -p cfg reindex
ragraf -p cfg status # file count AFTER — diff it
ragraf -p cfg query search "<a vanished module name>" # must be found againRule: extending the base exclusion list is allowed only if it drops zero files in every corpus; if even one file drops, the pattern goes into the specific corpus's config, where the directory's purpose is visible.
Symptom. The index has fewer files than the disk.
What it is. Identical-content copies collapse to one primary; disk files are untouched. Off by default (config.py:541). When on, index_status carries the discarded counters (copies, groups, bytes, lines — indexer.py:779-786).
Never change the primary-copy rule to «first one found»: ties must resolve by path, or the corpus checksum trembles and the guard loops (dedupe.py:165-223).
Remember: enabling collapsing changes the corpus checksum → the guard reindexes once. Conscious consequence, not a defect.
Portable check: run check twice in a row — the second run must NOT trigger reindexing.
Symptom. index_status shows the CPU computer; indexing slower than expected.
Causes, in check order:
- GPU disabled in settings (
embedding.use_gpu). - Workload below break-even: ~1800 texts (vectors) / ~5000 vertices (graph) — GPU map preparation costs ~15 s once, so small jobs legitimately lose (
config.py:276-301). -
sentence-transformers+torchnot installed — they are not declared dependencies (compute.py:141-146; roadmap R-PKG-1 adds agpuextra). - Free GPU memory below threshold → fallback with a reason.
Action: read the reason field of the compute state — it records the cause, not a guess. Do not lower thresholds «to make the GPU work»; that makes things slower.
Symptom: model download fails certificate verify failed (corporate proxy).
pip install truststore # or: install.ps1 -WithTruststoreMeasured: without → refusal; with → 240 MB in 9.2 s. Not needed at home. Cache dir: RAGRAF_MODEL_CACHE.
The refactored installer writes a transcript — attach it to issues: ~/.ragraf/logs/install-<ts>.log. Summary-table states: OK/WARN/FAIL/SKIP; exit codes 0/1/2/3.
| Failure row | Typical cause | Fix |
|---|---|---|
Python interpreter: Microsoft Store alias |
App Execution Alias, not an interpreter | python.org build, or disable the alias (Settings → Apps → Advanced app settings) |
Python >= 3.13: found 3.11 |
old interpreter | install 3.13+; or -Python <path>
|
venv module: missing |
embeddable/app-bundled Python | full distribution |
Free disk space |
<3 GB (or <4 with -Index) |
free space; the message states both numbers |
Create environment FAIL |
locked dir, no rights | check the transcript; choose another -Venv
|
cannot remove existing venv (-Force) |
a shell/IDE still uses it | close them, delete manually, re-run |
Install dependencies TIMEOUT |
slow proxy |
-TimeoutScale 3; -WithTruststore under TLS inspection |
pip exited with an error |
wheel build failure, network | last 4 stderr lines are in the row; full log in the transcript |
selftest: missing components |
see the component list in the row |
vec0_loadable → sqlite-vec wheel; embedding_model → first vector indexing downloads it; php_grammar → tree-sitter-language-pack |
Corpus ensure: not_a_project |
directory has no project markers | expected guard: point at a real project root |
| Symptom | Cause | Fix |
|---|---|---|
ragraf: command not found after install |
venv not activated | activate (~/.ragraf/venv/Scripts/Activate.ps1 / bin/activate) or call the full path |
'ragraf' is not a package from tools/ragraf.py
|
historical: the file shadowed the installed package | fixed (the wrapper strips tools/ from sys.path); update to the current revision |
«global flag rejected» (-p after subcommand) |
flag order |
--project/-p, --json go before the subcommand; ensure --json is the exception (after) |
error: argument op: invalid choice |
typo in operation name | the 23 valid names: Operations Reference |
| PowerShell profile interferes | scripts run with -NoProfile in docs for a reason |
invoke with pwsh -NoLogo -NoProfile -File …
|
- Write down the measurement: command, output, revision, checksum.
- Separate pre-existing from self-inflicted: does a fresh clone + clean venv reproduce it? (The doctrine checker's baseline in the author's environment was «2 errors, 0 warnings» — a third error was a finding.)
- Never report green without inspecting the object: every meaningful check has a counter of inspected items; zero-on-success is a false PASS.
Next: Benchmarks & Limits →