guzzle/promises · error · AggregateException
Not enough promises to fulfill count
Error message
Not enough promises to fulfill count
What it means
Utils::some($count, $promises) resolves only when at least $count of the given promises fulfill; it tracks every rejection in parallel. When all input promises have settled and fewer than $count fulfilled, it throws this AggregateException carrying all the collected rejection reasons. The library throws it to signal that the caller asked for more successes than the input set could ever produce.
Solutions
- Lower the $count argument so it is <= the number of promises that can realistically fulfill.
- Catch AggregateException and inspect getReason() to see why the inputs rejected, then retry the failed promises.
- Verify the input array actually contains at least $count promises.
- Replace some() with any() if only the first fulfillment matters, or use all()/settle() to observe every outcome.
Example fix
// before
$values = Utils::some(3, [$req1, $req2]); // only 2 promises: can never yield 3
// after
try {
$values = Utils::some(2, [$req1, $req2, $req3]);
} catch (AggregateException $e) {
foreach ($e->getReason() as $reason) { /* log/handle each rejection */ }
} Defensive patterns
Strategy: try-catch
Validate before calling
if ($count < 1) { throw new \InvalidArgumentException('$count must be >= 1'); }
if (count($promises) < $count) { throw new \LogicException('Fewer promises than requested count'); } Try / catch
try {
$values = \GuzzleHttp\Promise\Utils::some($count, $promises);
} catch (\GuzzleHttp\Promise\AggregateException $e) {
// $e->getReason() is the array of rejection reasons
$values = []; // fallback
} Prevention
- Always wrap some() calls in try-catch for AggregateException; partial failure is expected in racing patterns.
- Ensure $count <= count($promises) before calling.
- Prefer Utils::any() when only one success is needed.
- Inspect getReason() to decide which promises to retry.
When it happens
Trigger: Calling \GuzzleHttp\Promise\Utils::some($n, $promises) where fewer than $n promises fulfill: too many input promises reject (or the array has fewer than $n entries), so the counting composite settles with count($results) !== $count.
Common situations: Racing N parallel HTTP requests and asking for more successes than actually arrive; a transient outage makes most requests fail; passing a $count larger than the array length; retry logic built on some() that does not tolerate partial failure.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- You cannot create a FulfilledPromise with a promise.
- Cannot resolve a fulfilled promise
- Cannot reject a fulfilled promise
- should never be serialized
- should never be unserialized
AI-assisted analysis of guzzle/promises@42118e66a5 (2026-09-14).
Data as JSON: /api/errors/db3cff8a3a983d8b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Utils.php:277
$promise = Each::of(
$promises,
function ($value, $idx, PromiseInterface $p) use (&$results, $count): void {
if (Is::settled($p)) {
return;
}
$results[$idx] = $value;
if (count($results) >= $count) {
$p->resolve(null);
}
},
function ($reason) use (&$rejections): void {
$rejections[] = $reason;
}
)->then(
function () use (&$results, &$rejections, $count) {
if (count($results) !== $count) {
throw new AggregateException(
'Not enough promises to fulfill count',
$rejections
);
}
ksort($results);
return array_values($results);
}
);
/** @var PromiseInterface<list<TValue>, \Throwable> $promise */
return $promise;
}
/**
* Like some(), with 1 as count. However, if the promise fulfills, the
* fulfillment value is not an array of 1 but the value directly.
*View on GitHub (pinned to 42118e66a5)