ruvnet/ruflo · error · DarwinUnavailableError

Darwin archive incomplete

Error message

Darwin archive incomplete

What it means

When mode is 'darwin', the darwinInvoker ran but returned a result with completed: false (and an optional reason). Because the caller demanded Darwin, an incomplete archive is a hard DarwinUnavailableError rather than a silent fallback to the local proposer (which only happens for non-darwin modes).

Source

Thrown at v3/@claude-flow/cli/src/services/flywheel-proposer.ts:221

    const result = await Promise.race([
      input.darwinInvoker({
        baselinePolicy: input.baselinePolicy,
        seed: input.seed,
        budget: {
          maxEvaluationCostMicros: input.safetyEnvelope.maxEvaluationCostMicros,
          maxConcurrency: input.maxConcurrency ?? 2,
          maxWallTimeMs,
        },
      }),
      new Promise<never>((_, reject) => {
        timeout = setTimeout(() => reject(new DarwinUnavailableError('Darwin exceeded wall-time budget')), maxWallTimeMs);
        timeout.unref?.();
      }),
    ]).finally(() => {
      if (timeout) clearTimeout(timeout);
    });
    if (!result.completed) {
      if (input.mode === 'darwin') throw new DarwinUnavailableError(result.reason ?? 'Darwin archive incomplete');
      return runLocal(`darwin-incomplete:${result.reason ?? 'unknown'}`);
    }
    if (result.candidates.length > (input.maxCandidates ?? 256)) {
      throw new DarwinUnavailableError('Darwin archive exceeded candidate-count budget');
    }
    const evaluationCost = result.candidates.reduce(
      (sum, candidate) => sum + candidate.resources.evaluationCostMicros,
      0,
    );
    if (evaluationCost > input.safetyEnvelope.maxEvaluationCostMicros) {
      throw new DarwinUnavailableError('Darwin archive exceeded evaluation-cost budget');
    }
    return finalizeArchive({
      requested: input.mode,
      effective: 'darwin',
      promotionAllowed: true,
      baselineRef,
      safetyEnvelope: input.safetyEnvelope,

View on GitHub (pinned to 6b01dc5a68)

Solutions

  1. Inspect result.reason (surfaced in the message when present) to find the underlying cause.
  2. Retry with a fresh seed or a less constrained safetyEnvelope if reason indicates budget exhaustion.
  3. Fall back explicitly: if you can tolerate substitution, use mode 'auto' so an incomplete Darwin run falls back to local instead of throwing.
  4. Increase Darwin-side budgets/quotas if the reason is a Darwin-internal limit.

Example fix

// before
const archive = await proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, ... }); // throws if Darwin incomplete

// after — tolerate Darwin incompleteness via auto mode
const archive = await proposeFlywheelCandidates({ mode: 'auto', darwinInvoker, ... });
// archive.effective === 'local' with substitution 'darwin-incomplete:...' when Darwin fails
Defensive patterns

Strategy: try-catch

Validate before calling

// Cannot pre-validate Darwin's completion; choose a tolerant mode if substitution is acceptable:
await proposeFlywheelCandidates({ mode: 'auto', darwinInvoker, ... });

Try / catch

try {
  return await proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, ... });
} catch (e) {
  if (e instanceof DarwinUnavailableError) {
    // fall back to local explicitly
    return await proposeFlywheelCandidates({ mode: 'local', ... });
  }
  throw e;
}

Prevention

When it happens

Trigger: The Darwin backend signals it could not finish: internal error, resource exhaustion, partial failure, or it hit a limit and returned completed:false with result.reason set.

Common situations: Darwin's own budget/quota exhausted; the baseline policy or seed produced no viable candidates; Darwin service degraded or throttled; an upstream dependency of Darwin failed.

Related errors


AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12). Data as JSON: /api/errors/1fcbb8a5c1ab600f. Report an issue: GitHub.