abhigyanpatwari/GitNexus · error · GitNexusRcError

entry " " must be an identifier or member name (letters…

Error message

${source} entry "${trimmed}" must be an identifier or member name (letters, digits, _, $, . — e.g. "client.get").

What it means

The 'fetchWrappers' entries are interpolated into a RegExp alternation downstream, so the normalizer only accepts identifier or member-access shapes matching ^[A-Za-z_$][A-Za-z0-9_$.]*$. Anything else (brackets, spaces, dots in odd positions, glob or regex metacharacters) is rejected to prevent a config value from smuggling regex syntax into the consumer — a deliberate injection guard.

Solutions

  1. Use bare identifiers or dotted member paths: "fetch", "client.get", "axiosInstance.request"
  2. Remove parentheses, brackets, wildcards, and spaces — the message's example ("client.get") shows the accepted shape
  3. If you need broader matching, request a feature/config change rather than encoding a regex in the rc value

Example fix

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

Strategy: type-guard

Validate before calling

const IDENT = /^[A-Za-z_$][A-Za-z0-9_$.]*$/;
const bad = fw.filter((n: string) => !IDENT.test(n.trim()));
if (bad.length) throw new Error(`Invalid fetchWrappers entries: ${bad.join(', ')}`);

Type guard

type WrapperName = string;
const isWrapperName = (v: string): v is WrapperName =>
  /^[A-Za-z_$][A-Za-z0-9_$.]*$/.test(v);

Try / catch

catch (err) {
  if (err instanceof GitNexusRcError && err.message.includes('identifier or member name')) {
    // echo the accepted shape: bare identifiers or dotted member paths only
  }
}

Prevention

When it happens

Trigger: {"fetchWrappers": ["client['get']"]}, ["client.get.*"], ["my wrapper"], ["1abc"] (starts with a digit), or ["a b"]; the regex test at analyze-config.ts:272 fails and throws with the offending value echoed back.

Common situations: Trying to configure wrappers with glob or regex patterns ("fetch*", ".*(get|post)"), method-call syntax like "client.get()", or property-bracket access; users assume the config accepts patterns when it only accepts names.

Related errors


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

Appendix: source

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

      // 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) {
        throw new GitNexusRcError(`${source} must list at least one string.`);
      }
      // De-duplicate and cap to a sane bound so a pathological config cannot
      // blow up the consumer scan's alternation.
      return Array.from(new Set(names)).slice(0, 100);
    }
    case 'numeric-string': {
      // Mirror Commander's contract: these options reach the existing CLI
      // validation as strings. Accept a JSON number or a string; normalize to a
      // string and let the downstream per-flag validation enforce ranges so the
      // error messages stay in one place.

View on GitHub (pinned to ac9a4e9abd)