abhigyanpatwari/GitNexus · warning · GitNexusRcError

must not be empty.

Error message

${source} must not be empty.

What it means

A tree-sitter grammar (or variant key like `typescript:tsx`) failed to load; the failure is logged once per key (deduped in `logged`) as `[gitnexus] <note> (<error.message>)`, with severity routing: 'error' goes to logger.error (required grammar) and otherwise logger.warn. Both go to stderr so MCP stdio framing is preserved; that language's parsing is simply unavailable for the session.

Solutions

  1. Reinstall dependencies so grammars rebuild/re-materialize: remove node_modules and reinstall
  2. Install a C/C++ toolchain (python3, make, g++) if no prebuild matches your platform-arch
  3. For optional languages only, silence by setting GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1
  4. Check result.note in the message — it distinguishes 'skipped optional' (warn) from 'required grammar failed' (error)
Defensive patterns

Strategy: fallback

Validate before calling

import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
// preflight: can each required grammar's native module be loaded in this runtime?
const canLoadGrammar = ( moduleName: string): boolean => {
  try { require.resolve(moduleName); return true; } catch { return false; }
};
for (const g of ['tree-sitter', 'tree-sitter-typescript' /* , ... */]) {
  if (!canLoadGrammar(g)) logger.warn(`grammar unavailable at plan time: ${g}`);
}

Type guard

type LoadResult = { ok: boolean; severity?: 'error' | 'warn'; note: string; error: Error };
const isGrammarLoadFailure = (r: LoadResult): boolean => r.ok !== true;

Prevention

When it happens

Trigger: loadGrammar(key) returns a failed LoadResult — the vendored grammar native module is missing or unloadable: no committed prebuild matched platform-arch and no C/C++ toolchain was present to source-build, an ABI mismatch after a Node/LadybugDB bump, or a corrupted node_modules install.

Common situations: Fresh installs on uncommon platforms (musl, ARM variants) where the optional-grammar prebuild is absent; upgrading Node major versions without reinstalling (NODE_MODULE_VERSION mismatch); optional grammars (dart/proto/swift/kotlin) skipped via GITNEXUS_SKIP_OPTIONAL_GRAMMARS=1 or missing toolchain (python3/make/g++).

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@ac9a4e9abd (2026-08-20). Data as JSON: /api/errors/b5a9eaca56197148. Report an issue: GitHub.

Appendix: source

Thrown at gitnexus/src/cli/analyze-config.ts:224

      return validateBranchName(value, source);
    case 'path': {
      if (typeof value !== 'string') {
        throw new GitNexusRcError(`${source} must be a file or directory path.`);
      }
      const trimmed = value.trim();
      if (!trimmed) {
        throw new GitNexusRcError(`${source} must not be empty.`);
      }
      assertNoHiddenChars(trimmed, source);
      return trimmed;
    }
    case 'string': {
      if (typeof value !== 'string') {
        throw new GitNexusRcError(`${source} must be a string.`);
      }
      const trimmed = value.trim();
      if (!trimmed) {
        throw new GitNexusRcError(`${source} must not be empty.`);
      }
      assertNoHiddenChars(trimmed, source);
      // `name` flows into the generated AGENTS.md/CLAUDE.md as `**${name}**` and
      // inside `gitnexus://repo/${name}/…` code spans, so a Markdown-significant
      // character would break those spans or inject emphasis/links/HTML into
      // agent-instruction content (#1996 tri-review P1). `_` is intentionally
      // allowed (legitimate in repo names; intraword `_` is not emphasis).
      // embeddingDevice (the other `string`-kind option) only ever holds a
      // fixed device token, so this guard never rejects a valid value there.
      if (/[`*[\]<>]/.test(trimmed)) {
        throw new GitNexusRcError(
          `${source} must not contain Markdown-significant characters (\` * [ ] < >).`,
        );
      }
      return trimmed;
    }
    case 'string-array': {
      // Generic shared validator — `source` already names the config key, so

View on GitHub (pinned to ac9a4e9abd)