abhigyanpatwari/GitNexus · error · Error

must be a non-negative integer, got

Error message

${name} must be a non-negative integer, got "${raw}"

What it means

parseNonNegativeIntegerEnv() rejects non-digit values for GITNEXUS_EMBEDDING_MIN_INTERVAL_MS (the HTTP pacing floor between requests; fallback 0, max 300000). Unlike the positive variant, 0 is legal here — but '0x10', '1.5', '-5', or '1e3' still throw.

Solutions

  1. Use a bare integer of milliseconds: GITNEXUS_EMBEDDING_MIN_INTERVAL_MS=100.
  2. Unset the variable to use the default pacing (0).
  3. Verify no hidden characters in the value (the regex ^\d+$ is strict).

Example fix

# before
export GITNEXUS_EMBEDDING_MIN_INTERVAL_MS='100ms'
# after
export GITNEXUS_EMBEDDING_MIN_INTERVAL_MS=100
Defensive patterns

Strategy: validation

Validate before calling

const raw = process.env.GITNEXUS_EMBEDDING_MIN_INTERVAL_MS;
if (raw !== undefined && raw !== '' && !/^\d+$/.test(raw)) {
  throw new Error('GITNEXUS_EMBEDDING_MIN_INTERVAL_MS must be digits (milliseconds)');
}

Type guard

const isEnvFormatError = (e: unknown): boolean =>
  e instanceof Error && /must be a non-negative integer, got/.test(e.message);

Try / catch

try {
  await httpEmbed(texts);
} catch (e) {
  if (isEnvFormatError(e)) { /* fix or unset the env var; non-retryable config error */ }
  else throw e;
}

Prevention

When it happens

Trigger: Setting GITNEXUS_EMBEDDING_MIN_INTERVAL_MS to a float, hex, negative, or whitespace-polluted value while HTTP embedding mode (GITNEXUS_EMBEDDING_URL + GITNEXUS_EMBEDDING_MODEL) is active, then triggering any embed call that reads config.

Common situations: Throttling configuration copied from a provider docs page that uses decimals ('0.5 req/s') or units ('100ms'), or values injected via CI with stray quotes.

Related errors


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

Appendix: source

Thrown at gitnexus/src/core/embeddings/http-client.ts:71

const parsePositiveIntegerEnv = (name: string, fallback: number, max: number): number => {
  const raw = process.env[name];
  if (raw === undefined || raw === '') return fallback;
  if (!/^\d+$/u.test(raw)) {
    throw new Error(`${name} must be a positive integer, got "${raw}"`);
  }
  const parsed = Number(raw);
  if (!Number.isSafeInteger(parsed) || parsed <= 0 || parsed > max) {
    throw new Error(`${name} must be a positive integer <= ${max}, got "${raw}"`);
  }
  return parsed;
};

const parseNonNegativeIntegerEnv = (name: string, fallback: number, max: number): number => {
  const raw = process.env[name];
  if (raw === undefined || raw === '') return fallback;
  if (!/^\d+$/u.test(raw)) {
    throw new Error(`${name} must be a non-negative integer, got "${raw}"`);
  }
  const parsed = Number(raw);
  if (!Number.isSafeInteger(parsed) || parsed < 0 || parsed > max) {
    throw new Error(`${name} must be a non-negative integer <= ${max}, got "${raw}"`);
  }
  return parsed;
};

const cancelledError = (): DOMException =>
  new DOMException('Embedding request cancelled', 'AbortError');

const throwIfAborted = (signal?: AbortSignal): void => {
  if (signal?.aborted) throw cancelledError();
};

const abortableSleep = (ms: number, signal?: AbortSignal): Promise<void> => {
  throwIfAborted(signal);
  if (ms <= 0) return Promise.resolve();

View on GitHub (pinned to ac9a4e9abd)