abhigyanpatwari/GitNexus · warning
GitNexus query failed (degraded)
Error message
GitNexus query failed (degraded)
What it means
logQueryError is the MCP local backend's best-effort enrichment error funnel: a query failed non-benignly (timeouts, locks, native faults) and is logged at warn as 'degraded' — benign missing-table errors (repo analyzed without Process/Community tables) are demoted to debug. The doc comment on the helper is the contract: warn alone is not enough; mutating or safety-critical callers MUST also set a result-level signal (partial flag, failed_files, traversalComplete:false).
Source
Thrown at gitnexus/src/mcp/local/local-backend.ts:557
*
* `error` is intentionally NOT used here — it is reserved for failures that
* actually abort an operation, which log directly rather than through this
* best-effort-degradation helper.
*
* Contract for callers (#2283 review): only route a failure here when the
* caller ALSO surfaces the degradation in its result (a `partial` flag,
* `failed_files`, `traversalComplete:false`, …). A mutating or safety-critical
* path that would otherwise report success/clean (e.g. `rename` apply, the
* `detect_changes` safety gate) MUST set that result-level signal — `warn`
* alone is not a substitute for an honest result.
*/
function logQueryError(context: string, err: unknown): void {
const msg = err instanceof Error ? err.message : String(err);
if (isBenignMissingTableError(err)) {
logger.debug({ context, err: msg }, 'GitNexus query skipped (missing optional data)');
return;
}
logger.warn({ context, err: msg }, 'GitNexus query failed (degraded)');
}
/**
* A "missing table/label/relation" prepare error is benign for the query tool's
* best-effort enrichment: a repo analyzed without processes or communities simply
* has no `Process`/`Community` tables, so the `STEP_IN_PROCESS` / `MEMBER_OF`
* enrichment queries fail to prepare. That is a normal configuration, NOT a
* degraded result — it must not raise the `partial` flag (which callers would
* then learn to ignore). Real failures (timeouts, locks, native faults) do.
*/
function isBenignMissingTableError(err: unknown): boolean {
const msg = err instanceof Error ? err.message : String(err ?? '');
// The `not (defined|found)` arm is scoped to a schema object (table/label/
// rel/column/property), mirroring lbug-adapter's isMissingColumnError
// (`/(table|column|property).*not found/i`): an unscoped "not found" matched
// operation failures like `rg: not found` (ripgrep absent) or `Symbol not
// found`, which this helper would then silently demote to `debug` (#2283).
return /does not exist|no such (table|label|rel)|unknown (table|label)|(table|label|rel|column|property)[^\n]*\bnot (defined|found)\b/i.test(View on GitHub (pinned to aac7515d2a)
Solutions
- Check whether the result carries partial/failed_files/traversalComplete signals and treat it as degraded rather than clean.
- Let the concurrent analyze finish (or re-run it) and retry the query.
- Re-index if the index is old relative to the server version: `gitnexus analyze`.
- If the err in the log line is a lock/busy message, serialize access to the DB.
Defensive patterns
Strategy: try-catch
Type guard
function isBenignMissingTableError(err: unknown): boolean {
const msg = err instanceof Error ? err.message : String(err ?? '');
return /does not exist|Table: .* not found/i.test(msg);
} Try / catch
// Mirror the backend's own funnel: demote benign, escalate real, AND set result signals
try {
results = await enrich(queryResult);
} catch (err) {
if (isBenignMissingTableError(err)) logger.debug({ err });
else { logger.warn({ err }, 'degraded'); result.partial = true; }
} Prevention
- Never rely on the warn alone — check partial / failed_files / traversalComplete on results.
- Keep query traffic and analyze writes serialized per DB.
- Re-index after version upgrades so enrichment tables exist and benign misses shrink.
When it happens
Trigger: Any query tool enrichment sub-query throws something isBenignMissingTableError does not match: DB lock timeouts while serve/analyze run concurrently, engine native faults, corrupted tables. The surrounding tool still returns results but must carry the degradation signal for those specific paths.
Common situations: Querying an index while analyze is rewriting it; querying a repo indexed by a much older version (schema drift beyond the benign patterns); partial/corrupt DBs after disk issues.
Related errors
- Bridge query prepare failed: ${errMsg}
- Prepare failed: ${errMsg}
- Structural relationship count failed; the graph-write-collap
- Incremental importer BFS: dropped chunk ${chunkIndex} (${bat
- GitNexus: bm25-index.js import failed — falling back to sema
AI-assisted analysis of abhigyanpatwari/GitNexus@aac7515d2a (2026-08-20).
Data as JSON: /api/errors/071c02b0ad7f3bf6.
Report an issue: GitHub.