ruvnet/ruflo · error · DarwinUnavailableError
Darwin archive exceeded candidate-count budget
Error message
Darwin archive exceeded candidate-count budget
What it means
After a completed Darwin run, proposeFlywheelCandidates checks that result.candidates.length does not exceed maxCandidates (default 256). Exceeding it means Darwin produced more candidates than the caller budgeted for, which could blow downstream evaluation cost, so it throws DarwinUnavailableError.
Source
Thrown at v3/@claude-flow/cli/src/services/flywheel-proposer.ts:225
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,
seed: input.seed,
candidates: result.candidates,
completed: true,
});View on GitHub (pinned to 6b01dc5a68)
Solutions
- Raise input.maxCandidates to a value Darwin will stay under, if your evaluation budget allows.
- Configure Darwin's own candidate-generation limit so its output fits within maxCandidates.
- Use mode 'auto' so a budget overrun falls back to the local proposer instead of throwing.
- If overruns are persistent, cap candidates in the darwinInvoker wrapper before returning.
Example fix
// before
proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, maxCandidates: 8, ... }); // throws if Darwin returns >8
// after — align budgets, or cap inside the invoker
const cappedInvoker = async (req) => {
const r = await darwinInvoker(req);
return { ...r, candidates: r.candidates.slice(0, 256) };
};
proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker: cappedInvoker, maxCandidates: 256, ... }); Defensive patterns
Strategy: validation
Validate before calling
const maxCandidates = 256; // align with what Darwin will produce
await proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, maxCandidates, ... }); Try / catch
try {
return await proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, maxCandidates: 8, ... });
} catch (e) {
if (e instanceof DarwinUnavailableError && /candidate-count budget/.test(e.message)) {
return await proposeFlywheelCandidates({ mode: 'darwin', darwinInvoker, maxCandidates: 256, ... });
}
throw e;
} Prevention
- Size maxCandidates to Darwin's expected output volume.
- Cap candidate count inside the darwinInvoker wrapper if Darwin cannot self-limit.
- Use mode 'auto' so overruns fall back to local instead of throwing.
- Coordinate maxCandidates with the downstream evaluation budget.
When it happens
Trigger: The Darwin backend returns more candidates than input.maxCandidates (or the 256 default), e.g. Darwin ignored the budget or the caller set maxCandidates lower than Darwin's natural output.
Common situations: maxCandidates set tightly (e.g. 8) while Darwin generates dozens; a Darwin version change increases default output; maxCandidates not coordinated with Darwin's own generation count.
Related errors
- Darwin archive exceeded evaluation-cost budget
- Darwin explicitly requested but unavailable
- 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/e21897db523bb2d9.
Report an issue: GitHub.