abhigyanpatwari/GitNexus · error · GitNexusRcError

entries must all be strings.

Error message

${source} entries must all be strings.

What it means

Thrown while loading .gitnexusrc: the string-array validator (used by the 'fetchWrappers' key) found an array element that is not a string. GitNexus normalizes every rc value through per-kind validators before merging it into analyze options, so a heterogeneous array aborts startup with a GitNexusRcError naming the offending key.

Solutions

  1. Quote every element of fetchWrappers so the array is string-only: {"fetchWrappers": ["client.get", "fetch"]}
  2. Re-run node .gitnexus/run.cjs analyze (or your usual gitnexus command) to confirm the rc file now loads
  3. Validate .gitnexusrc with a JSON linter or jsonschema check in CI before it reaches the CLI

Example fix

// before (.gitnexusrc)
{"fetchWrappers": ["client.get", 42]}
// after
{"fetchWrappers": ["client.get"]}
Defensive patterns

Strategy: validation

Validate before calling

// Before running analyze, validate .gitnexusrc yourself:
import { readFileSync } from 'node:fs';
const rc = JSON.parse(readFileSync('.gitnexusrc', 'utf8'));
const fw = rc.fetchWrappers ?? rc.analyze?.fetchWrappers;
if (fw !== undefined && !(Array.isArray(fw) && fw.every((x) => typeof x === 'string'))) {
  throw new Error('fetchWrappers must be an array of strings');
}

Type guard

const isStringArray = (v: unknown): v is string[] =>
  Array.isArray(v) && v.every((x) => typeof x === 'string');

Try / catch

try {
  loadAnalyzeConfig(repoRoot);
} catch (err) {
  if (err instanceof GitNexusRcError) {
    console.error(`Bad .gitnexusrc: ${err.message}`); // message names the key
    process.exit(2);
  }
  throw err;
}

Prevention

When it happens

Trigger: A .gitnexusrc containing e.g. {"fetchWrappers": ["client.get", 42]} or [null], or the same under a nested "analyze" block; loadAnalyzeConfig(repoRoot) then throws before any indexing starts.

Common situations: Hand-editing .gitnexusrc and mixing types (a number instead of a quoted string), or generating the file from a script/CI template that serializes numbers unquoted; also pasting YAML-style lists into what must be strict JSON.

Related errors


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

Appendix: source

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

      // 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();
        if (!trimmed) {
          throw new GitNexusRcError(`${source} entries must not be empty.`);
        }
        assertNoHiddenChars(trimmed, source);
        // Values may be interpolated into a RegExp downstream. Restrict to
        // identifier / member-access shapes so a config value can never smuggle
        // regex metacharacters into a consumer.
        if (!/^[A-Za-z_$][A-Za-z0-9_$.]*$/.test(trimmed)) {
          throw new GitNexusRcError(
            `${source} entry "${trimmed}" must be an identifier or member name ` +
              `(letters, digits, _, $, . — e.g. "client.get").`,
          );
        }
        names.push(trimmed);
      }
      if (names.length === 0) {

View on GitHub (pinned to ac9a4e9abd)