laravel/framework · error · BindingResolutionException

Target [$concrete] is not instantiable.

Error message

Target [$concrete] is not instantiable.

What it means

Same notInstantiable() helper as error 108, but thrown when buildStack is empty - meaning the container was asked to directly resolve/build an interface or abstract class at the top level with no registered concrete binding. There is no surrounding build chain to report.

Solutions

  1. Register a binding for the abstract: $this->app->bind(SomeInterface::class, Concrete::class).
  2. Resolve via the alias/string key that was actually bound instead of the interface FQCN.
  3. Confirm the service provider that performs the binding is loaded (config/app.php or package discovery).
  4. Use make() with the concrete class directly if no polymorphism is needed.

Example fix

// before
$repo = app(MailerInterface::class); // unbound interface
// after
$this->app->bind(MailerInterface::class, SmtpMailer::class);
$repo = app(MailerInterface::class);
Defensive patterns

Strategy: validation

Validate before calling

// Before top-level resolution of an abstract/interface, verify it is bound.
$abstract = SomeInterface::class;
if (! app()->bound($abstract) && (interface_exists($abstract) || (new \ReflectionClass($abstract))->isAbstract())) {
    throw new RuntimeException("Abstract [$abstract] has no concrete binding; register it in a provider.");
}
app()->make($abstract);

Type guard

function isDirectlyResolvable(string $abstract, \Illuminate\Container\Container $c): bool
{
    if (interface_exists($abstract) || (class_exists($abstract) && (new \ReflectionClass($abstract))->isAbstract())) {
        return $c->bound($abstract);
    }
    return class_exists($abstract);
}

Try / catch

use Illuminate\Contracts\Container\BindingResolutionException;

try {
    $instance = app()->make($abstract);
} catch (BindingResolutionException $e) {
    if (str_contains($e->getMessage(), 'is not instantiable.')) {
        // bind the abstract or resolve the concrete class directly
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling $container->make(SomeInterface::class) or build(SomeInterface::class) with no binding; resolving an abstract key whose binding was never registered; resolving an abstract class marked abstract.

Common situations: Asking the service locator for a contract by its FQCN instead of the bound alias; provider that should bind the interface not loaded in the current environment (e.g. tests vs prod); interface renamed so the binding key no longer matches.

Related errors


AI-assisted analysis of laravel/framework@e0f6eb3518 (2026-08-11). Data as JSON: /api/errors/53a6956203fd5ccd. Report an issue: GitHub.

Appendix: source

Thrown at src/Illuminate/Container/Container.php:1436

    /**
     * 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);

            $message = "Target [$concrete] is not instantiable while building [$previous].";
        } else {
            $message = "Target [$concrete] is not instantiable.";
        }

        throw new BindingResolutionException($message);
    }

    /**
     * Throw an exception for an unresolvable primitive.
     *
     * @return void
     *
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     */
    protected function unresolvablePrimitive(ReflectionParameter $parameter)
    {
        $message = "Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}";

        throw new BindingResolutionException($message);
    }

    /**
     * Register a new before resolving callback for all types.

View on GitHub (pinned to e0f6eb3518)