cakephp/cakephp · error · InvalidArgumentException

Invalid time parameter. Ensure your time value can be…

Error message

Invalid time parameter. Ensure your time value can be parsed by strtotime

What it means

withCache() accepts a string|int for the `$time` parameter used to compute the Expires header. When a string is passed, it is parsed with strtotime(); if parsing fails, this InvalidArgumentException is thrown because the library cannot derive a valid expiration timestamp.

Solutions

  1. Fix the time string so strtotime() can parse it (e.g. '+1 day', '+3600 seconds')
  2. Pass an integer Unix timestamp instead of a string to skip strtotime parsing entirely
  3. Validate the string with strtotime($time) !== false before calling withCache()
  4. Check for typos and locale issues in dynamically built time expressions

Example fix

// before
$response = $response->withCache(time(), '+1 dayz');
// after
$response = $response->withCache(time(), time() + 86400);
Defensive patterns

Strategy: validation

Validate before calling

if (!is_int($time) && strtotime($time) === false) {
    throw new InvalidArgumentException("Unparseable time: {$time}");
}
$response = $response->withCache($since, $time);

Type guard

function isParseableTime(string|int $time): bool {
    return is_int($time) || strtotime($time) !== false;
}

Try / catch

try {
    $response = $response->withCache($since, $time);
} catch (InvalidArgumentException $e) {
    $response = $response->withCache($since, time() + 86400);
}

Prevention

When it happens

Trigger: Calling $response->withCache($since, $time) where $time is a non-integer string that strtotime() cannot parse, e.g. '+1 dayz', 'tomorrow at 25pm', '', or a locale-formatted date like 'morgen'.

Common situations: Hardcoded typo in a relative time expression; passing user-supplied date strings without validation; passing locale-dependent strings in non-English environments where strtotime expects English.

Related errors


AI-assisted analysis of cakephp/cakephp@1128eba9b0 (2026-09-12). Data as JSON: /api/errors/03a8e9da11d41a28. Report an issue: GitHub.

Appendix: source

Thrown at src/Http/Response.php:597

    {
        return $this->withHeader('Expires', 'Mon, 26 Jul 1997 05:00:00 GMT')
            ->withHeader('Last-Modified', CakeDateTime::parse(time())->toRfc7231String())
            ->withHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
    }

    /**
     * Create a new instance with the headers to enable client caching.
     *
     * @param string|int $since a valid time since the response text has not been modified
     * @param string|int $time a valid time for cache expiry
     * @return static
     */
    public function withCache(string|int $since, string|int $time = '+1 day'): static
    {
        if (!is_int($time)) {
            $time = strtotime($time);
            if ($time === false) {
                throw new InvalidArgumentException(
                    'Invalid time parameter. Ensure your time value can be parsed by strtotime',
                );
            }
        }

        return $this->withHeader('Date', CakeDateTime::parse(time())->toRfc7231String())
            ->withModified($since)
            ->withExpires($time)
            ->withSharable(true)
            ->withMaxAge($time - time());
    }

    /**
     * Create a new instance with the public/private Cache-Control directive set.
     *
     * @param bool $public If set to true, the Cache-Control header will be set as public
     *   if set to false, the response will be set to private.
     * @param int|null $time time in seconds after which the response should no longer be considered fresh.

View on GitHub (pinned to 1128eba9b0)