cakephp/cakephp · error · InvalidArgumentException

`flushEvery` must be an integer greater than or equal to 1

Error message

`flushEvery` must be an integer greater than or equal to 1

What it means

normalizeStreamOptions() validates the 'flushEvery' streaming option used by stream responses. It must be an integer >= 1 because it controls how many items are encoded between output flushes; zero, negative, or non-integer values are rejected with an InvalidArgumentException.

Solutions

  1. Pass flushEvery as an integer >= 1, e.g. (int)'10' or max(1, $n)
  2. Cast config values: (int)Configure::read('Streaming.flushEvery')
  3. Remove the flushEvery option to use the default instead of passing 0/null
  4. Use max(1, (int)$value) when deriving the value dynamically

Example fix

// before
$response->withStreamOptions(['flushEvery' => '10']);
// after
$response->withStreamOptions(['flushEvery' => max(1, (int)$configValue)]);
Defensive patterns

Strategy: validation

Validate before calling

$flushEvery = (int)($options['flushEvery'] ?? 100);
if ($flushEvery < 1) {
    $flushEvery = 1;
}
$response->withStreamOptions(['flushEvery' => $flushEvery]);

Type guard

function isValidFlushEvery(mixed $v): bool {
    return is_int($v) && $v >= 1;
}

Try / catch

try {
    $response = $response->withStreamOptions($options);
} catch (InvalidArgumentException $e) {
    $response = $response->withStreamOptions(['flushEvery' => 100]);
}

Prevention

When it happens

Trigger: Constructing an AbstractStreamResponse subclass (e.g. JsonStreamResponse) or calling withStreamOptions() with ['flushEvery' => 0], a negative number, a numeric string like '10', a float, or null.

Common situations: Passing the value from config/env as a string without casting; computing flushEvery with integer division or ceil() producing a float; defaulting the option to 0 meaning 'no flushing'.

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 cakephp/cakephp@1128eba9b0 (2026-09-12). Data as JSON: /api/errors/12231443df94c5dc. Report an issue: GitHub.

Appendix: source

Thrown at src/Http/Response/AbstractStreamResponse.php:151

     *
     * @return string
     */
    abstract protected function contentType(): string;

    /**
     * Validate and normalize the streaming options.
     *
     * Subclasses overriding this method should call `parent::normalizeStreamOptions()`
     * so the shared options (currently `flushEvery`) keep their validation.
     *
     * @param array<string, mixed> $options Merged options.
     * @param array<string, mixed> $originalOptions Original options passed by the caller.
     * @return array<string, mixed>
     */
    protected function normalizeStreamOptions(array $options, array $originalOptions = []): array
    {
        if (!is_int($options['flushEvery']) || $options['flushEvery'] < 1) {
            throw new InvalidArgumentException('`flushEvery` must be an integer greater than or equal to 1');
        }

        return $options;
    }

    /**
     * Apply headers derived from the active stream options.
     *
     * Sets the Content-Type (with charset) returned by {@see self::contentType()}
     * and `X-Accel-Buffering: no` so reverse proxies do not buffer the body.
     *
     * @return void
     */
    protected function applyStreamingHeaders(): void
    {
        $charset = Configure::read('App.encoding') ?? 'UTF-8';
        $contentType = $this->contentType() . '; charset=' . $charset;

View on GitHub (pinned to 1128eba9b0)