{"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/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Auth/AuthManager.php#L262-L298","documentation":"Thrown by AuthManager::extend() when bindCallbackToSelf() returns null. bindCallbackToSelf calls Closure::bindTo() on anonymous closures; bindTo returns null if PHP cannot rebind the closure to the requested scope, so the manager refuses to store an unusable creator.","triggerScenarios":"Calling Auth::extend('driver', $callback) where $callback is an anonymous closure that cannot be rebound to the AuthManager scope (e.g., a static closure whose bindTo with a scope fails, or a closure over incompatible bound state).","commonSituations":"Passing a static closure or a closure built from a non-object-bound context in a way that defeats rebinding; very rare in normal usage.","solutions":["Pass a regular (non-static) Closure so it can be rebound to the manager.","Avoid wrapping the callback with Closure::fromCallable on a method that carries incompatible scope.","If you need a static closure, build the guard instance explicitly and return it instead of relying on rebinding."],"exampleFix":"// before\nAuth::extend('custom', static function ($app, $name, $config) {\n    // static anonymous closure - bindTo may yield null\n    return new CustomGuard(...);\n});\n\n// after\nAuth::extend('custom', function ($app, $name, $config) {\n    return new CustomGuard($app, $name, $config);\n});","handlingStrategy":"validation","validationCode":"$callback = function ($app, $name, $config) { /* ... */ };\n$rebound = $callback->bindTo(app('auth.manager'), app('auth.manager')::class);\nif ($rebound === null) {\n    throw new RuntimeException('Closure cannot be rebound; use a non-static closure.');\n}\nAuth::extend('custom', $callback);","typeGuard":"function isRebindableClosure(\\Closure $c, object $scope): bool\n{\n    try {\n        return (new \\ReflectionFunction($c))->isAnonymous()\n            ? $c->bindTo($scope, $scope::class) !== null\n            : true;\n    } catch (\\ReflectionException) {\n        return false;\n    }\n}","tryCatchPattern":"try {\n    Auth::extend('custom', $callback);\n} catch (\\RuntimeException $e) {\n    // wrap with an invokable class instead\n    Auth::extend('custom', app(CustomGuardFactory::class));\n}","preventionTips":["Avoid static anonymous closures as driver creators.","Prefer invokable class instances over anonymous closures for creators.","Unit-test custom driver registration after defining it."],"tags":["authentication","extension","closure","laravel"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}