{"record":{"id":"37124dd4a1cc8c39","repo":"laravel/framework","slug":"unable-to-bind-custom-driver-callback","errorCode":null,"errorMessage":"Unable to bind custom driver callback","messagePattern":"Unable to bind custom driver callback","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Auth/AuthManager.php","lineNumber":280,"sourceCode":"        $this->userResolver = $userResolver;\n\n        return $this;\n    }\n\n    /**\n     * Register a custom driver creator Closure.\n     *\n     * @param  string  $driver\n     * @param  \\Closure  $callback\n     *\n     * @param-closure-this  $this  $callback\n     *\n     * @return $this\n     */\n    public function extend($driver, Closure $callback)\n    {\n        try {\n            $callback = $this->bindCallbackToSelf($callback) ?? throw new RuntimeException('Unable to bind custom driver callback');\n        } catch (ReflectionException $e) {\n            throw new RuntimeException('Unable to bind custom driver callback', previous: $e);\n        }\n\n        $this->customCreators[$driver] = $callback;\n\n        return $this;\n    }\n\n    /**\n     * Register a custom provider creator Closure.\n     *\n     * @param  string  $name\n     * @param  \\Closure  $callback\n     * @return $this\n     */\n    public function provider($name, Closure $callback)\n    {","sourceCodeStart":262,"sourceCodeEnd":298,"githubUrl":"https://github.com/laravel/framework/blob/e0f6eb3518ac29fbbca8529e97d0df7fc9f24481/src/Illuminate/Auth/AuthManager.php#L262-L298","documentation":"Thrown by AuthManager::extend() on the null-coalesce-throw line when bindCallbackToSelf($callback) returns null. extend() attempts to rebind the supplied Closure so that $this inside it refers to the AuthManager; if the rebinder cannot produce a bound closure (returns null), it throws this RuntimeException. This is distinct from the ReflectionException branch on the next line.","triggerScenarios":"Calling Auth::extend($driver, $callback) with a closure that bindCallbackToSelf refuses or cannot rebind (returns null), e.g. a static closure (Closure::bind returns null for static closures) or a Closure from an incompatible scope that cannot be rebound to the manager instance.","commonSituations":"Registering a custom auth driver with a static closure (static fn (...) => ...); passing a closure built from ReflectionClosure whose declared scope cannot be reassigned; edge cases after upgrading PHP where Closure::bind semantics changed for static closures.","solutions":["Pass a non-static closure so it can be rebound to the AuthManager instance.","If the closure must be static, restructure to avoid relying on $this binding, or wrap logic in an invokable class.","Ensure the closure is a real Closure (not a first-class callable string in a context that strips scope).","Confirm PHP version compatibility for Closure::bind / Closure::bindTo behavior."],"exampleFix":"// before — static closure cannot be rebound\nAuth::extend('jwt', static function ($app, array $config) {\n    return new JwtGuard(...);\n});\n\n// after — non-static closure\nAuth::extend('jwt', function ($app, array $config) {\n    return new JwtGuard(Auth::createUserProvider($config['provider'] ?? null));\n});","handlingStrategy":"validation","validationCode":"// PHP — ensure the closure is non-static and rebindable before extend()\n$ref = new \\ReflectionFunction($callback);\nif ($ref->isStatic()) {\n    throw new \\RuntimeException('Cannot extend() with a static closure; use a non-static closure.');\n}\nAuth::extend($driver, $callback);","typeGuard":"function isRebindableClosure(\\Closure $c): bool {\n    return ! (new \\ReflectionFunction($c))->isStatic();\n}","tryCatchPattern":"try {\n    Auth::extend($driver, $callback);\n} catch (\\RuntimeException $e) {\n    Log::error('Auth::extend failed to bind', ['driver' => $driver, 'err' => $e->getMessage()]);\n    throw $e;\n}","preventionTips":["Avoid static closures when calling Auth::extend().","Use invokable classes for complex custom drivers.","Register extend() in a service provider's boot() method."],"tags":["authentication","extend","closure-binding","laravel","php"],"backgroundTag":null,"analyzedSha":"e0f6eb3518ac29fbbca8529e97d0df7fc9f24481","analyzedAt":"2026-08-11T20:52:37.562Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}