| name | gitnexus-debugging |
| description | Use when the user is debugging a bug, tracing an error, or asking why something fails. Examples: "Why is X failing?", "Where does this error come from?", "Trace this bug" |
Debugging with GitNexus
When to Use
- "Why is this function failing?"
- "Trace where this error comes from"
- "Who calls this method?"
- "This endpoint returns 500"
- Investigating bugs, errors, or unexpected behavior
Bind the repository first
A root cause traced in the wrong repository is a wrong root cause.
Call list_repos {} before the first tool call. With one indexed repository,
use the examples below as written. With more than one, pass repo on every
call: an omitted repo normally errors, but under an MCP policy with a
configured default it resolves to that default silently. If you cannot tell
which repository is meant, stop and ask. This matters most for cypher, whose
statement carries no in-band hint of which database it ran against.
list_repos is paginated, so page with offset: pagination.nextOffset until
hasMore is false before concluding a repository is absent.
A stale index describes the code from before your bug, so refresh before
trusting a trace, and state the repository and index freshness with the
diagnosis.
Workflow
0. list_repos {} → Bind repo
1. query({search_query: "<error or symptom>"}) → Find related execution flows
2. context({name: "<suspect>"}) → See callers/callees/processes
3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow
4. cypher({statement: "MATCH path..."}) → Custom traces if needed
If "Index is stale" → run node .gitnexus/run.cjs analyze in terminal.
Checklist
- [ ] list_repos {} — bind repo; explicit repo when >1 indexed, ask if ambiguous
- [ ] Understand the symptom (error message, unexpected behavior)
- [ ] query for error text or related code
- [ ] Identify the suspect function from returned processes
- [ ] context to see callers and callees
- [ ] Trace execution flow via process resource if applicable
- [ ] cypher for custom call chain traces if needed
- [ ] Read source files to confirm root cause
- [ ] State the repository and index freshness with the diagnosis
Debugging Patterns
| Symptom | GitNexus Approach |
|---|
| Error message | query for error text → context on throw sites |
| Wrong return value | context on the function → trace callees for data flow |
| Intermittent failure | context → look for external calls, async deps |
| Performance issue | context → find symbols with many callers (hot paths) |
| Recent regression | detect_changes to see what your changes affect — pass worktree for a linked worktree |
| "How does A reach B?" | trace between the two symbols — shortest call chain in one call |
Tools
query — find code related to error:
query({search_query: "payment validation error", repo: "my-app"})
→ Processes: CheckoutFlow, ErrorHandling
→ Symbols: validatePayment, handlePaymentError, PaymentException
context — full context for a suspect:
context({name: "validatePayment", repo: "my-app"})
→ Incoming calls: processCheckout, webhookHandler
→ Outgoing calls: verifyCard, fetchRates (external API!)
→ Processes: CheckoutFlow (step 3/7)
cypher — custom call chain traces. Pass repo alongside the statement; the
Cypher text itself names no repository, so the result is unattributable without
it:
MATCH path = (a)-[:CodeRelation {type: 'CALLS'}*1..2]->(b:Function {name: "validatePayment"})
RETURN [n IN nodes(path) | n.name] AS chain
trace — shortest call chain between two symbols ("how does A reach B?"), one call instead of chaining context hops:
trace({ from: "processCheckout", to: "fetchRates", repo: "my-app" })
→ status: ok, hopCount: 3
→ hops: processCheckout → validatePayment → verifyCard → fetchRates
→ edges: CALLS (1.0), CALLS (0.95), CALLS (1.0)
When no path exists, trace reports the furthest reachable node — exactly where the chain breaks (dynamic dispatch, reflection, or an external boundary).
Example: "Payment endpoint returns 500 intermittently"
0. list_repos {}
→ total: 2 (my-app, billing-api) — bind my-app explicitly on every call
1. query({search_query: "payment error handling", repo: "my-app"})
→ Processes: CheckoutFlow, ErrorHandling
→ Symbols: validatePayment, handlePaymentError
2. context({name: "validatePayment", repo: "my-app"})
→ Outgoing calls: verifyCard, fetchRates (external API!)
3. READ gitnexus://repo/my-app/process/CheckoutFlow
→ Step 3: validatePayment → calls fetchRates (external)
4. Root cause: fetchRates calls external API without proper timeout
Repository: my-app Index: current
With a single indexed repository, step 0 returns total: 1 and the repo
argument drops out of every call above.