Skip to content

10 Troubleshooting

Mikhail Deynekin edited this page Oct 12, 2026 · 1 revision

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.


Quick triage

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

1. The index is stale or «trembling»

Symptom. Operations answer but facts mismatch the code; freshness reports divergence; check reindexes on every call.

Diagnosis.

ragraf -p cfg check
ragraf -p cfg status

check 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 reindex

If 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.

2. The registry shows an empty revision and zeros

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 check

Verification: catalog gains revision, counts, and a trigger like guard:fast / ensure:index.

3. capability=degraded

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 reason

Action.

  1. 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: a php ≥ 7.1 in PATH is mandatory (php2cpg shells out to it).
  2. Re-run indexing — the layer rebuilds.
  3. If refusal repeats: work without slice operations and record the finding. Known unlocalized case: export exit 1 with «next on empty iterator» while cpg.bin was 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».

4. An exclusion edit threw out working code

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 again

Rule: 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.

5. Duplicate collapsing and its price

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.

6. The computer fell back to CPU

Symptom. index_status shows the CPU computer; indexing slower than expected.

Causes, in check order:

  1. GPU disabled in settings (embedding.use_gpu).
  2. 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).
  3. sentence-transformers + torch not installed — they are not declared dependencies (compute.py:141-146; roadmap R-PKG-1 adds a gpu extra).
  4. 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.

7. TLS inspection

Symptom: model download fails certificate verify failed (corporate proxy).

pip install truststore        # or: install.ps1 -WithTruststore

Measured: without → refusal; with → 240 MB in 9.2 s. Not needed at home. Cache dir: RAGRAF_MODEL_CACHE.

8. Installer failures

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

9. Entry-point problems

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 …

10. Universal procedure (any weird state)

  1. Write down the measurement: command, output, revision, checksum.
  2. 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.)
  3. 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 →

Clone this wiki locally