laravel/framework · error · InvalidArgumentException
Method not provided.
Error message
Method not provided.
What it means
Thrown by BoundMethod::callClass when a Class@method string passed to Container::call contains only a class name (no '@method' segment) and no defaultMethod was supplied and the class has no __invoke method. Laravel needs a method to invoke and cannot guess it, so it raises InvalidArgumentException('Method not provided.').
Source
Thrown at src/Illuminate/Container/BoundMethod.php:63
* @param array $parameters
* @param string|null $defaultMethod
* @return mixed
*
* @throws \InvalidArgumentException
*/
protected static function callClass($container, $target, array $parameters = [], $defaultMethod = null)
{
$segments = explode('@', $target);
// We will assume an @ sign is used to delimit the class name from the method
// name. We will split on this @ sign and then build a callable array that
// we can pass right back into the "call" method for dependency binding.
$method = count($segments) === 2
? $segments[1]
: $defaultMethod;
if (is_null($method)) {
throw new InvalidArgumentException('Method not provided.');
}
return static::call(
$container,
[$container->make($segments[0]), $method],
$parameters
);
}
/**
* Call a method that has been bound to the container.
*
* @param \Illuminate\Container\Container $container
* @param callable $callback
* @param mixed $default
* @return mixed
*/
protected static function callBoundMethod($container, $callback, $default)View on GitHub (pinned to bd6b5437e6)
Solutions
- Provide the method explicitly: $container->call('App\Services\InvoiceService@process') or use array form [$instance, 'process'].
- Pass the defaultMethod argument: $container->call($class, [], 'handle').
- If the class is meant to be invoked, implement __invoke on it (the container auto-detects __invoke when no method is given).
- Switch to a Closure or [object, method] callable to remove ambiguity.
Example fix
// before app()->call(App\Services\ReportService::class); // after app()->call([app(ReportService::class), 'generate']); // or app()->call(ReportService::class, [], 'generate');
Defensive patterns
Strategy: validation
Validate before calling
if (is_string($callback) && ! str_contains($callback, '@')
&& ! method_exists($callback, '__invoke')) {
throw new \InvalidArgumentException("{$callback} needs '@method' or an __invoke method");
}
app()->call($callback, $params); Type guard
function isCallableMethodSpec(string|callable $callback): bool
{
if (! is_string($callback)) return true;
return str_contains($callback, '@') || method_exists($callback, '__invoke');
} Try / catch
try {
app()->call($callback, $params);
} catch (\InvalidArgumentException $e) {
if ($e->getMessage() === 'Method not provided.') {
app()->call($callback, $params, 'handle');
} else { throw $e; }
} Prevention
- Always pass Class@method or [instance, method] arrays.
- Implement __invoke on classes used as single-method services.
- Document the expected callable shape in your dispatcher's docblock.
When it happens
Trigger: Calling $container->call('App\Services\InvoiceService') with no @method and no third $defaultMethod argument, where InvoiceService has no __invoke. Also Scheduler/Job dispatch code that resolves 'Class' instead of 'Class@handle'.
Common situations: Passing a job class string to dispatch helpers that expect Class@method or a callable array; typo dropping the @method portion; refactoring an invokable class into a non-invokable one without updating callers; queued closures converted to class strings.
Related errors
- Unable to resolve dependency [{$parameter}] in class {$param
- {self::class}::bind(): Argument #2 ($concrete) must be of ty
- [{$abstract}] is aliased to itself.
- Target class [$concrete] does not exist.
- No newInstance method exists for [$concrete].
AI-assisted analysis of laravel/framework@bd6b5437e6 (2026-08-06).
Data as JSON: /data/errors/f1847c566b93e92a.json.
Report an issue: GitHub.