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

  1. 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))
  2. Guard with is_float($_SERVER['REQUEST_TIME_FLOAT']) before calling the formatter and fall back to computing Duration yourself from your own start timestamp
  3. 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

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


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)