sebastianbergmann/php-timer · error · TimeSinceStartOfRequestNotAvailableException
Cannot determine time at which the request started because…
Error message
Cannot determine time at which the request started because $_SERVER['REQUEST_TIME_FLOAT'] is not of type float
What it means
This exception is thrown when $_SERVER['REQUEST_TIME_FLOAT'] exists but is not of type float. The formatter requires the original float value PHP sets (microsecond-precision timestamp); if something has overwritten it with a string, int, or other type, the library refuses to compute a duration from it to avoid wrong results.
Solutions
- Ensure $_SERVER['REQUEST_TIME_FLOAT'] is the untouched float value PHP provides (remove any code that overwrites it, or restore it via $_SERVER['REQUEST_TIME_FLOAT'] = microtime(true))
- Guard with is_float($_SERVER['REQUEST_TIME_FLOAT']) before calling the formatter and fall back to computing Duration yourself from your own start timestamp
- Use ResourceUsageFormatter::resourceUsage(Duration) with an explicitly constructed Duration when you cannot trust the superglobal's type
Example fix
// before $_SERVER['REQUEST_TIME_FLOAT'] = time(); // int, breaks the formatter $usage = $formatter->resourceUsageSinceStartOfRequest(); // after $_SERVER['REQUEST_TIME_FLOAT'] = microtime(true); // float, as PHP SAPI sets it $usage = $formatter->resourceUsageSinceStartOfRequest();
Defensive patterns
Strategy: type-guard
Validate before calling
if (!is_float($_SERVER['REQUEST_TIME_FLOAT'] ?? null)) {
$_SERVER['REQUEST_TIME_FLOAT'] = microtime(true); // restore expected float type
}
Type guard
function hasFloatRequestTimeFloat(): bool
{
return isset($_SERVER['REQUEST_TIME_FLOAT']) && is_float($_SERVER['REQUEST_TIME_FLOAT']);
}
Try / catch
use SebastianBergmann\Timer\TimeSinceStartOfRequestNotAvailableException;
try {
$usage = $formatter->resourceUsageSinceStartOfRequest();
} catch (TimeSinceStartOfRequestNotAvailableException $e) {
$usage = $formatter->resourceUsage(Duration::fromMicroseconds((microtime(true) - $fallbackStart) * 1000000));
}
Prevention
- Never overwrite $_SERVER['REQUEST_TIME_FLOAT'] with non-float values (time() returns int)
- Cast any custom value to float: (float) $value before assigning to the superglobal
- Audit bootstrap/middleware/test fixtures that modify $_SERVER
- Prefer passing an explicit Duration to resourceUsage() over relying on the superglobal
When it happens
Trigger: Calling resourceUsageSinceStartOfRequest() after application/framework/test-bootstrap code has coerced or overwritten $_SERVER['REQUEST_TIME_FLOAT'] (e.g. setlocale/string casts, custom middleware writing a string timestamp, test fixtures replacing the superglobal with an int or array value).
Common situations: Custom bootstrap scripts that do $_SERVER['REQUEST_TIME_FLOAT'] = time() (an int); frameworks or telemetry tools that stringify superglobals; integration tests seeding $_SERVER manually with wrong types; polyfills or older SAPIs setting an unexpected type.
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
- Cannot determine time at which the request started because…
- Timer::start() has to be called before Timer::stop()
AI-assisted analysis of sebastianbergmann/php-timer@3efcdcf213 (2026-09-13).
Data as JSON: /api/errors/b46ae197e7c29362.
Report an issue: GitHub.
Appendix: source
Thrown at src/ResourceUsageFormatter.php:49
'Time: %s, Memory: %s',
$duration->asString(),
$this->bytesToString(memory_get_peak_usage(true)),
);
}
/**
* @throws TimeSinceStartOfRequestNotAvailableException
*/
public function resourceUsageSinceStartOfRequest(): string
{
if (!isset($_SERVER['REQUEST_TIME_FLOAT'])) {
throw new TimeSinceStartOfRequestNotAvailableException(
'Cannot determine time at which the request started because $_SERVER[\'REQUEST_TIME_FLOAT\'] is not available',
);
}
if (!is_float($_SERVER['REQUEST_TIME_FLOAT'])) {
throw new TimeSinceStartOfRequestNotAvailableException(
'Cannot determine time at which the request started because $_SERVER[\'REQUEST_TIME_FLOAT\'] is not of type float',
);
}
return $this->resourceUsage(
Duration::fromMicroseconds(
(1000000 * (microtime(true) - $_SERVER['REQUEST_TIME_FLOAT'])),
),
);
}
private function bytesToString(int $bytes): string
{
foreach (self::SIZES as $unit => $value) {
if ($bytes >= $value) {
return sprintf('%.2f %s', $bytes / $value, $unit);
}
}View on GitHub (pinned to 3efcdcf213)