laravel/framework · error · BindingResolutionException

Unable to resolve dependency [{$parameter}] in class {$param

Error message

Unable to resolve dependency [{$parameter}] in class {$parameter->getDeclaringClass()->getName()}

What it means

Thrown by BoundMethod::addDependencyForCallParameter while Container::call injects dependencies for a closure/method. When a parameter has no type-hinted class, no contextual attribute, no default value, is not optional, and is not present in the supplied parameters array, the container cannot supply a value and throws BindingResolutionException naming the parameter and its declaring class.

Source

Thrown at src/Illuminate/Container/BoundMethod.php:200

                unset($parameters[$className]);
            } elseif ($parameter->isVariadic()) {
                $variadicDependencies = $container->make($className);

                $pendingDependencies = array_merge($pendingDependencies, is_array($variadicDependencies)
                    ? $variadicDependencies
                    : [$variadicDependencies]);
            } elseif ($parameter->isDefaultValueAvailable() && ! $container->bound($className)) {
                $pendingDependencies[] = $parameter->getDefaultValue();
            } else {
                $pendingDependencies[] = $container->make($className);
            }
        } elseif ($parameter->isDefaultValueAvailable()) {
            $pendingDependencies[] = $parameter->getDefaultValue();
        } elseif (! $parameter->isOptional() && ! array_key_exists($paramName, $parameters)) {
            $message = "Unable to resolve dependency [{$parameter}] in class {$parameter->getDeclaringClass()->getName()}";

            throw new BindingResolutionException($message);
        }

        foreach ($pendingDependencies as $dependency) {
            $container->fireAfterResolvingAttributeCallbacks($parameter->getAttributes(), $dependency);
        }

        $dependencies = array_merge($dependencies, $pendingDependencies);
    }

    /**
     * Determine if the given string is in Class@method syntax.
     *
     * @param  mixed  $callback
     * @return bool
     */
    protected static function isCallableWithAtSign($callback)
    {
        return is_string($callback) && str_contains($callback, '@');

View on GitHub (pinned to bd6b5437e6)

Solutions

  1. Pass the missing parameter by name in the parameters array: $container->call([$obj, 'send'], ['message' => $body]).
  2. Give the parameter a default value ($message = '') or make it nullable / optional.
  3. Add a class type-hint so the container can auto-resolve it, or register a contextual binding for the primitive ('$message' => ...).

Example fix

// before
public function send(Mailer $mailer, string $message): void {...}
app()->call([$service, 'send'], []);

// after
app()->call([$service, 'send'], ['message' => 'Hello']);
Defensive patterns

Strategy: try-catch

Validate before calling

$reflection = new \ReflectionMethod($service, 'send');
$missing = [];
foreach ($reflection->getParameters() as $p) {
    if (! $p->isOptional()
        && $p->getClass() === null
        && ! array_key_exists($p->getName(), $params)) {
        $missing[] = $p->getName();
    }
}
if ($missing) throw new \InvalidArgumentException('Missing params: '.implode(',', $missing));
app()->call([$service, 'send'], $params);

Type guard

function allRequiredParamsProvidied(object $obj, string $method, array $params): bool
{
    $r = new \ReflectionMethod($obj, $method);
    foreach ($r->getParameters() as $p) {
        if (! $p->isOptional() && $p->getType() === null && ! array_key_exists($p->getName(), $params)) {
            return false;
        }
    }
    return true;
}

Try / catch

use Illuminate\Contracts\Container\BindingResolutionException;
try {
    app()->call([$service, 'send'], $params);
} catch (BindingResolutionException $e) {
    if (str_starts_with($e->getMessage(), 'Unable to resolve dependency')) {
        // log and supply default, or rethrow as domain error
    }
    throw $e;
}

Prevention

When it happens

Trigger: Calling $container->call([$obj, 'send'], ['to' => 'x']) where send(Mailer $mailer, $message) has an untyped $message with no default and 'message' was not passed. Any method invoked via call() with a required untyped/missing scalar or object parameter.

Common situations: Refactoring a method signature to add a new required parameter without updating all Container::call sites; passing positional instead of named parameters (call() resolves by name); a service method that needs a primitive the caller forgot.

Related errors


AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06). Data as JSON: /data/errors/d2548de1c2f8c9aa.json. Report an issue: GitHub.