abhigyanpatwari/GitNexus · error · Error

must be a positive integer, got

Error message

${name} must be a positive integer, got "${raw}"

What it means

parsePositiveIntegerEnv() rejects values that are not pure digit strings. It reads one of the HTTP embedding tuning vars — GITNEXUS_EMBEDDING_MAX_ATTEMPTS (max 20), GITNEXUS_EMBEDDING_RETRY_CAP_MS (max 300000), GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS (max 300000) — when HTTP embedding mode is configured. Malformed values throw at readConfig() time inside httpEmbed/httpEmbedQuery; isHttpMode() never reads them and never throws.

Solutions

  1. Set the variable to a bare positive integer without units, signs, decimals, or whitespace (e.g. GITNEXUS_EMBEDDING_MAX_ATTEMPTS=5).
  2. Unset the variable to fall back to the built-in default.
  3. Check the exact name spelled in the error (${name}) — that is the offending variable.
  4. Audit .env / CI secret for invisible characters (trailing \n, BOM).

Example fix

# before
export GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS='30s'
# after
export GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS=30000
Defensive patterns

Strategy: validation

Validate before calling

const assertDigits = (name: string): void => {
  const raw = process.env[name];
  if (raw !== undefined && raw !== '' && !/^\d+$/.test(raw)) {
    throw new Error(`${name} must be digits, got "${raw}"`);
  }
};
['GITNEXUS_EMBEDDING_MAX_ATTEMPTS','GITNEXUS_EMBEDDING_RETRY_CAP_MS','GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS'].forEach(assertDigits);

Type guard

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

Try / catch

try {
  await httpEmbed(texts);
} catch (e) {
  if (isEnvFormatError(e)) {
    // config bug: fix the env var named in the message and exit — retrying cannot help
    process.exitCode = 2;
  } else throw e;
}

Prevention

When it happens

Trigger: Setting e.g. GITNEXUS_EMBEDDING_MAX_ATTEMPTS='3x', GITNEXUS_EMBEDDING_HTTP_TIMEOUT_MS='1.5' (float), '-1' (sign), '1e3' (exponent), or ' 5' (whitespace) alongside GITNEXUS_EMBEDDING_URL and GITNEXUS_EMBEDDING_MODEL, then running any embedding operation.

Common situations: Copy-pasting values with units ('30s'), floats, scientific notation, or trailing whitespace/newlines from CI secrets or .env files; quoting mistakes in docker-compose YAML.

Related errors


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

Appendix: source

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

  retryCapMs: number;
  minIntervalMs: number;
  timeoutMs: number;
  retryTimeouts: boolean;
  requestDimensions?: number;
}

export interface EmbeddingRequestOptions {
  signal?: AbortSignal;
}

let lastHttpRequestStartedAt: number | undefined;
let httpPaceQueue: Promise<void> = Promise.resolve();

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}"`);
  }

View on GitHub (pinned to ac9a4e9abd)