abhigyanpatwari/GitNexus · error · Error

checkpointEveryNodes must be a positive integer

Error message

checkpointEveryNodes must be a positive integer

What it means

Thrown by runEmbeddingPipeline() when pipelineOptions.checkpointEveryNodes is present and is not a safe positive integer. The value (default 5000) controls how often the pipeline checkpoints progress by interleaving DELETE-then-INSERT batches; a non-integer, zero, negative, or beyond-MAX_SAFE_INTEGER value would produce malformed batch boundaries or skip checkpointing entirely.

Source

Thrown at gitnexus/src/core/embeddings/embedding-pipeline.ts:544

 *        and re-embedded; nodes not in the map are embedded fresh.
 */
export const runEmbeddingPipeline = async (
  executeQuery: (cypher: string) => Promise<any[]>,
  executeWithReusedStatement: (
    cypher: string,
    paramsList: Array<Record<string, any>>,
  ) => Promise<void>,
  onProgress: EmbeddingProgressCallback,
  config: Partial<EmbeddingConfig> = {},
  skipNodeIds?: Set<string>,
  existingEmbeddings?: Map<string, string>,
  pipelineOptions: EmbeddingPipelineOptions = {},
): Promise<EmbeddingPipelineResult> => {
  const finalConfig = resolveEmbeddingConfig(config);
  let totalChunks = 0;
  const checkpointEveryNodes = pipelineOptions.checkpointEveryNodes ?? 5_000;
  if (!Number.isSafeInteger(checkpointEveryNodes) || checkpointEveryNodes <= 0) {
    throw new Error('checkpointEveryNodes must be a positive integer');
  }
  const throwIfCancelled = (): void => pipelineOptions.signal?.throwIfAborted();

  try {
    throwIfCancelled();
    const vectorAvailable = await ensureVectorExtensionAvailable();
    throwIfCancelled();
    if (!vectorAvailable) {
      logger.warn(vectorUnavailableMessage);
    }

    // Phase 1: Load embedding model
    onProgress({
      phase: 'loading-model',
      percent: 0,
      modelDownloadPercent: 0,
    });

View on GitHub (pinned to d540b00184)

Solutions

  1. Pass checkpointEveryNodes as a positive integer, e.g. { checkpointEveryNodes: 5000 }.
  2. Omit the option to accept the 5000-node default.
  3. To effectively disable checkpointing for a small run, pass a value larger than the expected node count rather than 0.

Example fix

// before
await runEmbeddingPipeline(eq, ex, onProgress, {}, undefined, undefined, {
  checkpointEveryNodes: 0,
});
// after
await runEmbeddingPipeline(eq, ex, onProgress, {}, undefined, undefined, {
  checkpointEveryNodes: 100_000,
});
Defensive patterns

Strategy: validation

Validate before calling

const assertCheckpoint = (v: unknown): void => {
  if (v !== undefined && (!Number.isSafeInteger(v as number) || (v as number) <= 0)) {
    throw new Error('pipelineOptions.checkpointEveryNodes must be a positive integer (omit for 5000 default).');
  }
};
assertCheckpoint(pipelineOptions.checkpointEveryNodes);

Type guard

const isPositiveSafeInteger = (v: unknown): v is number =>
  typeof v === 'number' && Number.isSafeInteger(v) && v > 0;

Prevention

When it happens

Trigger: Programmatic callers of runEmbeddingPipeline passing pipelineOptions.checkpointEveryNodes as a float (e.g. 500.5), a string ('5000'), zero, or a negative number. The CLI does not expose this option, so it is almost always a custom integration or a test harness.

Common situations: A wrapper script passing a computed checkpoint interval that evaluated to a float; passing a value read from a config file as a string; a test using 0 to disable checkpointing (use a very large value instead).

Related errors


AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12). Data as JSON: /api/errors/2c6eae6a25365ed5. Report an issue: GitHub.