serbanghita/Mobile-Detect · error · BadMethodCallException

No such method exists: $name

Error message

No such method exists: $name

What it means

MobileDetect implements its magic isXXXX() API through __call() (src/MobileDetect.php:1395): any undefined method whose name starts with 'is' (isIphone(), isAndroidOS(), isChrome()) is forwarded to is($ruleName) and matched against the rule arrays. Any other undefined method name throws this BadMethodCallException instead of returning null or false — a fail-fast design so typos in real method names surface immediately.

Source

Thrown at src/MobileDetect.php:1395

        }

        return false;
    }

    /**
     * Magic overloading method.
     *
     * @param string $name
     * @param array $arguments
     * @return bool
     * @throws BadMethodCallException when the method doesn't exist and doesn't start with 'is'
     * @throws \Exception
     */
    public function __call(string $name, array $arguments): bool
    {
        // make sure the name starts with 'is', otherwise
        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);
        }

View on GitHub (pinned to 6ab7b0404d)

Solutions

  1. Check the real API first: method_exists($detect, $name) for concrete methods; for the magic rules, verify the suffix after 'is' against the rule arrays (getRules(), or the vendor fixtures in tests/providers/vendors/).
  2. Correct the call to an existing name: setUserAgent(), getUserAgent(), isMobile(), isTablet(), is(), version().
  3. For dynamic dispatch, whitelist before calling: allow only method_exists() names or strings matching /^is[A-Z]/.

Example fix

// before
$detect->getMobileHeaders(); // BadMethodCallException: No such method exists: getMobileHeaders

// after
$detect->setUserAgent($ua);
$isAndroid = $detect->isAndroidOS(); // 'AndroidOS' is a real operating-system rule
$isMobile  = $detect->isMobile();     // concrete method
Defensive patterns

Strategy: validation

Validate before calling

$method = 'is' . ucfirst($rule);
if (!method_exists($detect, $method) && !preg_match('/^is[A-Z]/', $method)) {
    throw new \BadMethodCallException("Unknown detection rule: $rule");
}
$result = $detect->$method();

Type guard

function isMagicDetectorCall(string $method): bool
{
    // concrete API first, then the 'is' + RuleName convention handled by __call
    return method_exists(MobileDetect::class, $method)
        || (str_starts_with($method, 'is') && strlen($method) > 2);
}

Try / catch

try {
    $ok = $detect->{$name}();
} catch (\BadMethodCallException $e) {
    // $name came from config/input and maps to no method; skip
    $ok = false;
}

Prevention

When it happens

Trigger: $detect->getUserAge() (typo of getUserAgent), $detect->detectMobile(), $detect->mobileDetect(), or dynamic calls $detect->{$method}() where $method comes from config/routing and doesn't begin with 'is'. Note that names that DO start with 'is' never throw here — they fall through to is() and match against the rules (unknown rules simply return false).

Common situations: Calls to methods removed or renamed across versions (e.g. older getters); IDE auto-completion or AI-generated code inventing names like detectMobile() or userAgent(); dynamic dispatch built from user input without a whitelist.

Related errors


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