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

  1. Provide the method explicitly: $container->call('App\Services\InvoiceService@process') or use array form [$instance, 'process'].
  2. Pass the defaultMethod argument: $container->call($class, [], 'handle').
  3. If the class is meant to be invoked, implement __invoke on it (the container auto-detects __invoke when no method is given).
  4. 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

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


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