laravel/framework · error · BindingResolutionException

Unresolvable dependency resolving [$parameter] in class

Error message

Unresolvable dependency resolving [$parameter] in class {$parameter->getDeclaringClass()->getName()}

What it means

BindingResolutionException from unresolvablePrimitive() when the container, while building a class, encounters a constructor parameter that is a primitive (non-class: int, string, bool, etc.), has no default value, and was not provided as an override. The container cannot guess a value for primitive parameters.

Solutions

  1. Pass the value explicitly: $container->make(MyClass::class, ['timeout' => 30]).
  2. Add a default value to the primitive parameter in the class.
  3. Bind the parameter contextually using Context::when(...) needs ['$timeout' => 30].
  4. Construct such objects with new instead of the container if they are plain value objects.

Example fix

// before
class HttpClient
{
    public function __construct(private int $timeout, private Logger $log) {}
}
app(HttpClient::class); // throws
// after
app(HttpClient::class, ['timeout' => 30]);
// or
$this->app->when(HttpClient::class)
    ->needs('$timeout')
    ->give(config('http.timeout'));
Defensive patterns

Strategy: validation

Validate before calling

// Identify required primitive constructor params and supply them.
$r = new \ReflectionClass(HttpClient::class);
$needed = [];
foreach ($r->getConstructor()?->getParameters() ?? [] as $p) {
    $t = $p->getType();
    if ($t && $t->isBuiltin() && ! $p->isDefaultValueAvailable() && ! $p->isOptional()) {
        $needed[$p->getName()] = config("http.{$p->getName()}");
    }
}
app()->make(HttpClient::class, $needed);

Type guard

function hasUnresolvablePrimitive(string $class): bool
{
    foreach ((new \ReflectionClass($class))->getConstructor()?->getParameters() ?? [] as $p) {
        $t = $p->getType();
        if ($t && $t->isBuiltin() && ! $p->isDefaultValueAvailable() && ! $p->isOptional()) {
            return true;
        }
    }
    return false;
}

Try / catch

use Illuminate\Contracts\Container\BindingResolutionException;

try {
    app()->make(HttpClient::class);
} catch (BindingResolutionException $e) {
    if (str_contains($e->getMessage(), 'Unresolvable dependency resolving')) {
        // supply the primitive via make() overrides or contextual binding
        app()->make(HttpClient::class, ['timeout' => 30]);
    }
    throw $e;
}

Prevention

When it happens

Trigger: Constructing a class like new class (int $timeout, Logger $log) where $timeout has no default and is not passed; resolving such a class via make() without overrides; a value-object with required scalar constructor args resolved through the container.

Common situations: Adding a required scalar config value to a constructor and forgetting to bind it; resolving value objects/DTOs through the container instead of new; refactor turning a method param into a constructor param without a default.

Related errors


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

Appendix: source

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

        } 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.
     *
     * @param  \Closure|string  $abstract
     * @return void
     */
    public function beforeResolving($abstract, ?Closure $callback = null)
    {
        if (is_string($abstract)) {
            $abstract = $this->getAlias($abstract);
        }

        if ($abstract instanceof Closure && is_null($callback)) {
            $this->globalBeforeResolvingCallbacks[] = $abstract;
        } else {
            $this->beforeResolvingCallbacks[$abstract][] = $callback;

View on GitHub (pinned to e0f6eb3518)