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

  1. Lower the $count argument so it is <= the number of promises that can realistically fulfill.
  2. Catch AggregateException and inspect getReason() to see why the inputs rejected, then retry the failed promises.
  3. Verify the input array actually contains at least $count promises.
  4. 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

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


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)