abhigyanpatwari/GitNexus · warning · Error

withRetry: maxAttempts must be >= 1, got ${opts.maxAttempts}

Error message

withRetry: maxAttempts must be >= 1, got ${opts.maxAttempts}

What it means

An optional LadybugDB (DuckDB-lineage) extension failed to load, so GitNexus continues without that extension's features. The degradation is deduped per `${name}:${reason}` key so it warns once, and a quiet probe deliberately skips the dedup key so the owning caller reports the real degradation later. The message embeds a diagnosis from diagnoseExtensionLoad explaining why loading failed.

Source

Thrown at gitnexus-shared/src/integrations/retry.ts:79

  }
  const exponential = baseDelayMs * Math.pow(2, attempt);
  const upper = Math.min(capDelayMs, exponential);
  return Math.floor(random() * upper);
}

/**
 * Execute `fn` with bounded retries.
 *
 * The classification of "retryable" is the caller's responsibility — see
 * `resilient-fetch.ts` for the GitHub-dispatch-specific rules. This
 * helper is the mechanical retry loop only.
 */
export async function withRetry<T>(
  fn: (attempt: number) => Promise<T>,
  opts: RetryOptions,
): Promise<T> {
  if (opts.maxAttempts < 1) {
    throw new Error(`withRetry: maxAttempts must be >= 1, got ${opts.maxAttempts}`);
  }
  const sleep = opts.sleep ?? defaultSleep;
  const random = opts.random ?? Math.random;

  let lastError: unknown;
  for (let attempt = 0; attempt < opts.maxAttempts; attempt++) {
    try {
      return await fn(attempt);
    } catch (err) {
      lastError = err;
      const decision = opts.isRetryable(err, attempt);
      if (!decision.retry) throw err;
      // Don't sleep after the final attempt.
      if (attempt + 1 >= opts.maxAttempts) break;
      const delayMs = computeBackoffMs(
        attempt,
        opts.baseDelayMs,
        opts.capDelayMs,

View on GitHub (pinned to aac7515d2a)

Solutions

  1. Reinstall or refresh the extension bundle so it matches the installed LadybugDB version
  2. Check the `reason` / diagnosis in the message to identify the exact load failure (missing file vs incompatible version vs load error)
  3. Verify platform/arch support for the extension on the current runtime
  4. If the feature is unneeded, ignore the warning — core operation continues without it

Example fix

// after init: gate features on actual capabilities
import { getExtensionCapabilities } from 'gitnexus/dist/core/lbug/extension-loader.js';
const caps = getExtensionCapabilities();
const hasJson = caps.some((c) => c.name === 'json' && c.loaded);
if (hasJson) { /* use json-extension-backed path */ } else { /* generic fallback path */ }
Defensive patterns

Strategy: fallback

Validate before calling

import { getExtensionCapabilities } from 'gitnexus/dist/core/lbug/extension-loader.js';
// after init: confirm the features you depend on actually loaded
const caps = getExtensionCapabilities();
const loaded = new Set(caps.filter((c) => c.loaded).map((c) => c.name));
if (!loaded.has('json')) {
  // take the non-extension code path instead of assuming the feature exists
}

Type guard

type ExtensionCapability = { name: string; loaded: boolean };
const isCapabilityAvailable = (caps: ExtensionCapability[], name: string): boolean =>
  caps.some((c) => c.name === name && c.loaded);

Prevention

When it happens

Trigger: ExtensionManager.load() fails for an optional extension — binary not installed for the platform/arch, LadybugDB version incompatible with the extension ABI, offline/filtered download of the extension bundle, or a corrupted extension file in the extensions directory.

Common situations: Upgrading LadybugDB without reinstalling matching extensions; air-gapped CI where the extension never got fetched; mixed-version installs where an extension built for an older ABI is present; musl-vs-glibc Linux mismatches.

Related errors


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