laravel/framework · error · BindingResolutionException
Contextual binding attribute
Error message
Contextual binding attribute [{$attribute->getName()}] has no registered handler. What it means
BindingResolutionException from resolveFromAttribute() when a PHP 8 attribute applied to an injectable parameter has neither a registered contextual-attribute handler in the container nor a resolve() method on the attribute instance itself. The container resolves such attributes either via a registered Closure or by calling $instance->resolve(); if neither exists it cannot produce a value.
Solutions
- Register a handler: Illuminate\Container\Context::registerAttribute(MyAttribute::class, fn (...) => $value) or set $container->contextualAttributes[MyAttribute::class].
- Add a public resolve() method to the attribute class returning the injected value.
- Ensure the service provider that registers contextual attributes is actually loaded in config/app.php.
- Verify the attribute FQCN used in code matches the registered key exactly (namespace/renaming).
Example fix
// before
#[StorageDisk('tmp')]
public function __construct(private $disk) {}
// no handler registered
// after
// in a service provider boot():
Context::registerAttribute(StorageDisk::class, function (StorageDisk $attr, Container $c) {
return Storage::disk($attr->disk);
}); Defensive patterns
Strategy: validation
Validate before calling
// Ensure every attribute used in injection has a handler.
use Illuminate\Container\Context;
$attrClass = MyAttribute::class;
if (! isset(app()->contextualAttributes[$attrClass]) && ! method_exists($attrClass, 'resolve')) {
Context::registerAttribute($attrClass, function (\ReflectionAttribute $a, $container, $parameter) {
return /* resolved value */;
});
} Type guard
function attributeHasHandler(string $attributeClass, \Illuminate\Container\Container $c): bool
{
return isset($c->contextualAttributes[$attributeClass])
|| method_exists($attributeClass, 'resolve');
} Try / catch
use Illuminate\Contracts\Container\BindingResolutionException;
try {
$instance = app()->make(UsesAttributes::class);
} catch (BindingResolutionException $e) {
if (str_contains($e->getMessage(), 'Contextual binding attribute')) {
// register the attribute handler in a provider, then retry
}
throw $e;
} Prevention
- Register all contextual attribute handlers in a single boot() step in your app provider.
- Add a resolve() method to attribute classes as a self-contained fallback handler.
- Write a boot-time smoke test that resolves every attribute-using service.
When it happens
Trigger: Using a custom #[MyAttribute] attribute on a constructor parameter but never registering it via Context::registerAttribute() / $container->contextualAttributes[]; using a built-in attribute whose handler registration was skipped; attribute class implemented without a resolve() method.
Common situations: Migrating to PHP 8 attribute-based injection without wiring the handler; package providing the attribute but its service provider not loaded; renaming the attribute class so the registered FQCN no longer matches.
Related errors
- {$id}
- Illuminate\Container\Container::bind(): Argument #2…
- Method not provided.
- No newInstance method exists for [$concrete].
- Target [$concrete] is not instantiable.
AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11).
Data as JSON: /api/errors/8bfd3e6c32d1c482.
Report an issue: GitHub.
Appendix: source
Thrown at src/Illuminate/Container/Container.php:1412
/**
* Resolve a dependency based on an attribute.
*
* @return mixed
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
public function resolveFromAttribute(ReflectionAttribute $attribute, ReflectionParameter $parameter)
{
$handler = $this->contextualAttributes[$attribute->getName()] ?? null;
$instance = $attribute->newInstance();
if (is_null($handler) && method_exists($instance, 'resolve')) {
$handler = $instance->resolve(...);
}
if (is_null($handler)) {
throw new BindingResolutionException("Contextual binding attribute [{$attribute->getName()}] has no registered handler.");
}
return $handler($instance, $this, $parameter);
}
/**
* Throw an exception that the concrete is not instantiable.
*
* @param string $concrete
* @return void
*
* @throws \Illuminate\Contracts\Container\BindingResolutionException
*/
protected function notInstantiable($concrete)
{
if (! empty($this->buildStack)) {
$previous = implode(', ', $this->buildStack);
View on GitHub (pinned to e0f6eb3518)