abhigyanpatwari/GitNexus · warning · GitNexusRcError

must not contain Markdown-significant characters (` * [ ] <…

Error message

${source} must not contain Markdown-significant characters (` * [ ] < >).

What it means

The source text handed to tree-sitter contained embedded NUL bytes (\0), which break tree-sitter parsing. safeParse replaces every NUL with a space (counting them, and tagging the log with the file label) before calling parser.parse, so parsing proceeds on sanitized text. It is a data-hygiene warning: offsets are preserved (1:1 replacement), but the file itself contains binary garbage or an encoding issue.

Solutions

  1. Inspect the named file around the NUL bytes (e.g. grep -P '\x00' or a hex view) and fix its encoding or truncate the binary prefix
  2. If the file is genuinely binary, exclude it from indexing so it never reaches the parser
  3. For UTF-16 sources, re-encode as UTF-8 before committing
  4. No code change needed — sanitization is automatic and lossless in length

Example fix

// before: binary-ish file goes straight to the parser
const tree = safeParse(parser, sourceText);

// after: pre-sanitize (or exclude) binary content
const sourceText = fileText.replaceAll('\0', ' '); // what safeParse does internally
const tree = safeParse(parser, sourceText);
Defensive patterns

Strategy: fallback

Validate before calling

// before parsing: detect and sanitize (1:1, length-preserving) like safeParse does
const sanitizeNuls = (text: string): { text: string; nulCount: number } => {
  let nulCount = 0;
  const clean = text.replaceAll('\0', () => { nulCount += 1; return ' '; });
  return { text: clean, nulCount };
};

Type guard

const hasEmbeddedNuls = (buf: Buffer | string): boolean =>
  typeof buf === 'string' ? buf.includes('\0') : buf.includes(0); // 0 byte = binary suspect

Prevention

When it happens

Trigger: sourceText.includes('\0') at parse entry — files with stray binary bytes (mangled merges, embedded binary blobs), UTF-16 files read as UTF-8 (NUL-filled high bytes), or tooling that writes text with C-string terminators.

Common situations: Repos containing pseudo-binary files with text extensions (.ts, .json) that pass extension filters; files transcoded badly between encodings; fixtures generated from binary templates. Column positions survive because each NUL becomes exactly one space.

Related errors


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

Appendix: source

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

    }
    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
      // messages here stay key-agnostic (no fetch-wrapper coupling in the
      // shared normalizer; #1589/#1852 review F7).
      if (!Array.isArray(value)) {
        throw new GitNexusRcError(`${source} must be an array of strings.`);
      }
      const names: string[] = [];
      for (const item of value) {
        if (typeof item !== 'string') {
          throw new GitNexusRcError(`${source} entries must all be strings.`);
        }
        const trimmed = item.trim();

View on GitHub (pinned to ac9a4e9abd)