ruvnet/ruflo · error · DarwinUnavailableError
Darwin archive exceeded evaluation-cost budget
Error message
Darwin archive exceeded evaluation-cost budget
What it means
proposeFlywheelCandidates sums evaluationCostMicros across all Darwin candidates and throws DarwinUnavailableError if the total exceeds safetyEnvelope.maxEvaluationCostMicros. This enforces the caller-declared evaluation spend ceiling before any candidate is evaluated downstream.
Source
Thrown at v3/@claude-flow/cli/src/services/flywheel-proposer.ts:232
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,
seed: input.seed,
candidates: result.candidates,
completed: true,
});
} catch (error) {
if (input.mode === 'darwin') {
if (error instanceof DarwinUnavailableError) throw error;
throw new DarwinUnavailableError(`Darwin failed closed: ${(error as Error).message}`);
}
return runLocal(`darwin-error:${(error as Error).message}`);
}View on GitHub (pinned to 6b01dc5a68)
Solutions
- Raise safetyEnvelope.maxEvaluationCostMicros to match the expected Darwin archive cost.
- Reduce the candidate count (lower maxCandidates) so the summed cost fits.
- Filter cheap candidates only inside the darwinInvoker wrapper before returning.
- Switch to mode 'auto' so a cost overrun falls back to local instead of throwing.
Example fix
// before
proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, safetyEnvelope: { maxEvaluationCostMicros: 1_000_000, ... }, ... }); // throws on cost overrun
// after — size the envelope to the archive, or trim expensive candidates
const trimmed = async (req) => {
const r = await darwinInvoker(req);
let cost = 0; const keep = [];
for (const c of r.candidates) {
if (cost + c.resources.evaluationCostMicros > req.budget.maxEvaluationCostMicros) break;
cost += c.resources.evaluationCostMicros; keep.push(c);
}
return { ...r, candidates: keep };
};
proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker: trimmed, ... }); Defensive patterns
Strategy: validation
Validate before calling
const safetyEnvelope = { ...input.safetyEnvelope, maxEvaluationCostMicros: Math.max(input.safetyEnvelope.maxEvaluationCostMicros, expectedArchiveCost) };
await proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, safetyEnvelope, ... }); Try / catch
try {
return await proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, safetyEnvelope, ... });
} catch (e) {
if (e instanceof DarwinUnavailableError && /evaluation-cost budget/.test(e.message)) {
// raise the envelope or trim expensive candidates and retry
return await proposeFlywheelCandidates({ mode: 'auto', darwinInvoker, safetyEnvelope: { ...safetyEnvelope, maxEvaluationCostMicros: safetyEnvelope.maxEvaluationCostMicros * 2 }, ... });
}
throw e;
} Prevention
- Size maxEvaluationCostMicros to the expected summed Darwin archive cost.
- Trim expensive candidates inside the darwinInvoker wrapper before returning.
- Keep maxCandidates and per-candidate evaluationCostMicros within the envelope.
- Use mode 'auto' to fall back to local on cost overruns.
When it happens
Trigger: The combined per-candidate evaluation cost of Darwin's archive is larger than the safety envelope's maxEvaluationCostMicros — many candidates each with non-trivial evaluationCostMicros, or a few very expensive candidates.
Common situations: safetyEnvelope.maxEvaluationCostMicros set too low for the candidate volume; Darwin candidates carry high evaluationCostMicros (expensive models/large evals); the envelope was sized for the local proposer's smaller output.
Related errors
- Darwin explicitly requested but unavailable
- Darwin archive exceeded candidate-count budget
- Darwin archive incomplete
- Darwin failed closed: ${(error as Error).message}
- no eligible peers for exploration
AI-assisted analysis of ruvnet/ruflo@6b01dc5a68 (2026-08-12).
Data as JSON: /api/errors/21f11173bcc60a5b.
Report an issue: GitHub.