doctrine/cache · error · TypeError
Expected $time to be either an integer, an instance of…
Error message
Expected $time to be either an integer, an instance of DateInterval or null, got %s
What it means
TypedCacheItem::expiresAfter() accepts null, int seconds, or DateInterval; anything else raises a TypeError with the debug type embedded via get_debug_type(). This mirrors CacheItem::expiresAfter but in the typed item class.
Solutions
- Cast to int: expiresAfter((int) $ttl)
- Convert interval strings with new DateInterval($spec)
- Use expiresAt() with DateTimeImmutable for absolute expiry
Example fix
// before
$item->expiresAfter(getenv('CACHE_TTL')); // string
// after
$item->expiresAfter((int) getenv('CACHE_TTL')); Defensive patterns
Strategy: type-guard
Validate before calling
if ($time !== null && !is_int($time) && !$time instanceof \DateInterval) { throw new InvalidArgumentException('time must be int, DateInterval or null'); } Type guard
function acceptsTtl(mixed $v): bool { return $v === null || is_int($v) || $v instanceof \DateInterval; } Try / catch
try { $item->expiresAfter($ttl); } catch (\TypeError $e) { /* coerce or report */ } Prevention
- Cast env/config TTLs to int at config load
- Use DateInterval for interval strings
- Keep absolute and relative expiry APIs distinct in your code
When it happens
Trigger: Calling expiresAfter() with a string TTL from config/env, a float, or a DateTime object instead of the accepted types.
Common situations: TTL values sourced from .env or JSON as strings; refactors moving from untyped to typed cache items; passing DateInterval where int was expected is fine, but strings are not auto-parsed.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Expected $time to be either an integer, an instance of…
- Expected $expiration to be an instance of DateTimeInterface…
- Expected $expiration to be an instance of DateTimeInterface…
- Cache key must be string
- Cache key length must be greater than zero.
AI-assisted analysis of doctrine/cache@e0a9919443 (2026-09-13).
Data as JSON: /api/errors/573f51e7495a4325.
Report an issue: GitHub.
Appendix: source
Thrown at lib/Doctrine/Common/Cache/Psr6/TypedCacheItem.php:83
));
}
return $this;
}
/**
* {@inheritDoc}
*/
public function expiresAfter($time): static
{
if ($time === null) {
$this->expiry = null;
} elseif ($time instanceof DateInterval) {
$this->expiry = microtime(true) + DateTime::createFromFormat('U', 0)->add($time)->format('U.u');
} elseif (is_int($time)) {
$this->expiry = $time + microtime(true);
} else {
throw new TypeError(sprintf(
'Expected $time to be either an integer, an instance of DateInterval or null, got %s',
get_debug_type($time)
));
}
return $this;
}
/**
* @internal
*/
public function getExpiry(): ?float
{
return $this->expiry;
}
}
View on GitHub (pinned to e0a9919443)