serbanghita/Mobile-Detect · error · MobileDetectException

INVALID_USER_AGENT_ERR

INVALID_USER_AGENT_ERR

Error message

No valid user-agent has been set.

What it means

isMobile() requires a User-Agent to have been set: hasUserAgent() (src/MobileDetect.php:1271) returns true only when the userAgent property is a string, so null throws MobileDetectException with code INVALID_USER_AGENT_ERR (0x1) before any detection runs. With the default 'autoInitOfHttpHeaders' => true the constructor pulls $_SERVER['HTTP_USER_AGENT'], so this mainly fires when auto-init is disabled or no such header exists in the environment. An empty-string UA does not throw — isMobile() returns false for it.

Source

Thrown at src/MobileDetect.php:1412

        if (!str_starts_with($name, 'is')) {
            throw new BadMethodCallException("No such method exists: $name");
        }

        $ruleName = substr($name, 2);

        return $this->is($ruleName);
    }

    /**
     * Check if the device is mobile.
     * Returns true if any type of mobile device detected, including special ones
     * @return bool
     * @throws MobileDetectException
     */
    public function isMobile(): bool
    {
        if (!$this->hasUserAgent()) {
            throw new MobileDetectException('No valid user-agent has been set.', MobileDetectExceptionCode::INVALID_USER_AGENT_ERR);
        }

        if ($this->isUserAgentEmpty()) {
            return false;
        }

        // Cache check.
        try {
            $cacheKey = $this->createCacheKey("mobile");
            $cacheItem = $this->cache->get($cacheKey);
            if ($cacheItem !== null) {
                return $cacheItem;
            }

            // Special case: Amazon CloudFront mobile viewer
            if (
                $this->getUserAgent() === static::$cloudFrontUA &&
                $this->getHttpHeader('HTTP_CLOUDFRONT_IS_MOBILE_VIEWER') === 'true'

View on GitHub (pinned to 6ab7b0404d)

Solutions

  1. Set the UA before detection: $detect->setUserAgent($request->headers->get('User-Agent', '')); pull it from the Request object, not $_SERVER.
  2. If you disable autoInit for performance (as the config comment suggests), make setUserAgent() part of your per-request bootstrap.
  3. For genuinely optional detection, guard first: if ($detect->hasUserAgent()) { ... } — or pass '' to get a deterministic false.

Example fix

// before
$detect = new MobileDetect(['autoInitOfHttpHeaders' => false]);
$detect->isMobile(); // throws: No valid user-agent has been set.

// after
$detect = new MobileDetect(['autoInitOfHttpHeaders' => false]);
$detect->setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) ...');
$detect->isMobile(); // bool
Defensive patterns

Strategy: validation

Validate before calling

if (!$detect->hasUserAgent()) {
    $detect->setUserAgent($request->headers->get('User-Agent', ''));
}
$isMobile = $detect->isMobile(); // no longer throws for missing UA

Type guard

// MobileDetect::hasUserAgent(): bool is the built-in guard — call it first
if ($detect->hasUserAgent() && !$detect->isUserAgentEmpty()) {
    $isMobile = $detect->isMobile();
}

Try / catch

use Detection\Exception\MobileDetectException;
use Detection\Exception\MobileDetectExceptionCode;

try {
    $isMobile = $detect->isMobile();
} catch (MobileDetectException $e) {
    if ($e->getCode() === MobileDetectExceptionCode::INVALID_USER_AGENT_ERR) {
        $isMobile = false; // no UA available; treat as non-mobile
    } else {
        throw $e;
    }
}

Prevention

When it happens

Trigger: Constructing with ['autoInitOfHttpHeaders' => false] and never calling setUserAgent(); running in CLI, queue workers, cron or PHPUnit where $_SERVER['HTTP_USER_AGENT'] is absent; long-running runtimes (Octane, Swoole, RoadRunner, FrankenPHP worker) where the detector is built before a request exists; calling isMobile() on a fresh instance in a test without a UA fixture.

Common situations: Upgrading from 2.x, where isMobile() silently returned false for a missing UA — 4.x makes it an explicit error, so legacy paths that never set a UA start throwing; framework batch jobs and CI pipelines where the HTTP superglobals are never populated; API-to-API endpoints where the client sends no User-Agent header.

Related errors


AI-assisted analysis of serbanghita/Mobile-Detect@6ab7b0404d (2026-08-21). Data as JSON: /api/errors/9cbea5070c60b9dd. Report an issue: GitHub.