serbanghita/Mobile-Detect · error · MobileDetectException
IS_MAGIC_ERR
IS_MAGIC_ERR
Error message
Cache problem in is(): {$e->getMessage()} What it means
is() (src/MobileDetect.php:1548) re-throws any CacheException, CacheInvalidArgumentException, or Psr\SimpleCache\InvalidArgumentException raised during its cache get/set or during createCacheKey() as MobileDetectException with code IS_MAGIC_ERR (0x4), chaining the cause. Because every magic isXXXX() call routes through __call -> is(), this is the wrapper you hit when cache trouble occurs inside a magic detection call (e.g. isIphone(), isBot()).
Source
Thrown at src/MobileDetect.php:1548
if ($this->isUserAgentEmpty()) {
return false;
}
// Cache check.
try {
$cacheKey = $this->createCacheKey($ruleName);
$cacheItem = $this->cache->get($cacheKey);
if ($cacheItem !== null) {
return $cacheItem;
}
$result = $this->matchUserAgentWithRule($ruleName);
// Cache save.
$this->cache->set($cacheKey, $result, $this->config['cacheTtl']);
return $result;
} catch (CacheInvalidArgumentException | CacheException | PsrInvalidArgumentException $e) {
throw new MobileDetectException("Cache problem in is(): {$e->getMessage()}", MobileDetectExceptionCode::IS_MAGIC_ERR, $e);
}
}
/**
* Some detection rules are relative (not standard),
* because of the diversity of devices, vendors and
* their conventions in representing the User-Agent or
* the HTTP headers.
*
* This method will be used to check custom regexes against
* the User-Agent string.
*
* @param string $regex
* @param string $userAgent
* @return bool
*
* @todo: search in the HTTP headers too.
*/View on GitHub (pinned to 6ab7b0404d)
Solutions
- Drill into the cause: $e->getPrevious() — 'cacheKeyFn is not a function.' means a config problem; 'Invalid key: ...' means the key fn output violates the charset rule.
- Restore a callable hash for 'cacheKeyFn' ('sha1' default, 'md5', or a hash() closure).
- Audit the custom CacheInterface implementation's exact get/set signatures and failure modes; have backend outages return defaults or log rather than throw when detection is non-critical.
- Catch narrowly by code (IS_MAGIC_ERR) so genuine detection bugs aren't swallowed.
Example fix
// before
if ($detect->isBot()) { /* ... */ } // Redis down -> IS_MAGIC_ERR wrapper
// after
use Detection\Exception\MobileDetectException;
use Detection\Exception\MobileDetectExceptionCode;
try {
$bot = $detect->isBot();
} catch (MobileDetectException $e) {
if ($e->getCode() !== MobileDetectExceptionCode::IS_MAGIC_ERR) {
throw $e;
}
$bot = false; // cache degraded; log $e->getPrevious()->getMessage()
} Defensive patterns
Strategy: try-catch
Validate before calling
// Guard the two root causes before any magic call:
$config = ['cacheKeyFn' => 'sha1'];
assert(is_callable($config['cacheKeyFn']));
// and prove the backend round-trips one MobileDetect-shaped key:
$cache->set(str_repeat('a', 40), true, 1); Type guard
// The bundled default never fails; guard only swapped-in backends:
function backendAcceptsDetectorKeys(\Psr\SimpleCache\CacheInterface $c): bool
{
try {
return $c->set(str_repeat('a', 40), 1, 1);
} catch (\Throwable) {
return false;
}
} Try / catch
catch (MobileDetectException $e) {
if ($e->getCode() === MobileDetectExceptionCode::IS_MAGIC_ERR) {
// is()/isXXXX() cache path failed; retry cache-less
$fresh = new \Detection\MobileDetect();
$fresh->setUserAgent($ua);
$result = $fresh->is($rule);
} else {
throw $e;
}
} Prevention
- Remember every isXXXX() funnels through is() — one bad cache config breaks all magic calls at once.
- Validate cacheKeyFn output shape in a boot-time smoke test, not in the request path.
- Distinguish by code: IS_MAGIC_ERR (0x4) means cache trouble, not a bad rule name.
When it happens
Trigger: $detect->isIphone() with 'cacheKeyFn' misconfigured (non-callable, or producing keys that fail checkKey) — the inner CacheException/CacheInvalidArgumentException originates in createCacheKey() or the Cache; a custom PSR-16 backend injected instead of the bundled Cache throwing on get/set (Redis down, strict key validation, unserializable values).
Common situations: Surfaces only after replacing the default in-memory cache with a real backend (default Cache + sha1 keys always pass validation); production-only cache outages; DI misconfiguration after a framework upgrade; per-user UA-flag caching with keys built outside MobileDetect.
Related errors
- IS_MOBILE_ERR
- IS_TABLET_ERR
- Cache key must be a string.
- Invalid key: '$key'. Must be alphanumeric, can contain _ and
- TTL must be null, int, or DateInterval.
AI-assisted analysis of serbanghita/Mobile-Detect@6ab7b0404d (2026-08-21).
Data as JSON: /api/errors/e7eb807823d0085d.
Report an issue: GitHub.