{"id":"4bfdd2a046c2ea37","repo":"laravel/framework","slug":"s-reducespread-expects-reducer-to-return-an-arra","errorCode":null,"errorMessage":"%s::reduceSpread expects reducer to return an array, but got a '%s' instead.","messagePattern":"(.+?)::reduceSpread expects reducer to return an array, but got a '(.+?)' instead\\.","errorType":"exception","errorClass":"UnexpectedValueException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Collections/Traits/EnumeratesValues.php","lineNumber":889,"sourceCode":"\n    /**\n     * Reduce the collection to multiple aggregate values.\n     *\n     * @param  callable  $callback\n     * @param  mixed  ...$initial\n     * @return array\n     *\n     * @throws \\UnexpectedValueException\n     */\n    public function reduceSpread(callable $callback, ...$initial)\n    {\n        $result = $initial;\n\n        foreach ($this as $key => $value) {\n            $result = call_user_func_array($callback, array_merge($result, [$value, $key]));\n\n            if (! is_array($result)) {\n                throw new UnexpectedValueException(sprintf(\n                    \"%s::reduceSpread expects reducer to return an array, but got a '%s' instead.\",\n                    class_basename(static::class), gettype($result)\n                ));\n            }\n        }\n\n        return $result;\n    }\n\n    /**\n     * Reduce an associative collection to a single value.\n     *\n     * @template TReduceWithKeysInitial\n     * @template TReduceWithKeysReturnType\n     *\n     * @param  callable(TReduceWithKeysInitial|TReduceWithKeysReturnType, TValue, TKey): TReduceWithKeysReturnType  $callback\n     * @param  TReduceWithKeysInitial  $initial\n     * @return TReduceWithKeysInitial|TReduceWithKeysReturnType","sourceCodeStart":871,"sourceCodeEnd":907,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Collections/Traits/EnumeratesValues.php#L871-L907","documentation":"Thrown by reduceSpread() when the reducer callback returns a non-array value on any iteration. reduceSpread spreads the accumulator array into the next callback call (like JS array destructuring), so the callback must always return an array. UnexpectedValueException reports the actual returned type.","triggerScenarios":"Calling $collection->reduceSpread(fn ($sum, $count, $item) => $sum + $item) where the callback returns a scalar. Forgetting to return an array, or an early return/break path returning null.","commonSituations":"Misunderstanding reduceSpread semantics (treating it like reduce). Refactoring from a scalar reduce() without updating the callback to return an array. A branch in the callback that forgets to return.","solutions":["Ensure the callback always returns an array; add a return statement on every branch.","If you want a scalar accumulator, use reduce() instead of reduceSpread().","Add a unit test asserting the callback's return type."],"exampleFix":"// before\n[$sum, $count] = $collection->reduceSpread(\n    fn ($sum, $count, $item) => $sum + $item->price\n);\n\n// after\n[$sum, $count] = $collection->reduceSpread(\n    fn ($sum, $count, $item) => [$sum + $item->price, $count + 1]\n);","handlingStrategy":"type-guard","validationCode":"// verify the reducer returns array before reduceSpread\n$probe = $callback(...[...$initial, $collection->first(), 0]);\nif (! is_array($probe)) {\n    throw new \\LogicException('reducer must return an array');\n}","typeGuard":"function returnsArray(callable $cb, array $args): bool {\n    return is_array($cb(...$args));\n}","tryCatchPattern":"try {\n    [$a, $b] = $collection->reduceSpread($cb);\n} catch (\\UnexpectedValueException $e) {\n    // fix the callback to always return an array; reduceSpread can't recover\n    throw $e;\n}","preventionTips":["Use reduce() when you need a scalar accumulator; reserve reduceSpread() for tuple/array accumulators.","Always return an array on every branch of the reducer callback.","Unit-test the reducer in isolation to confirm it returns an array."],"tags":["laravel","collections","callback-contract","type-safety"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}