barryvdh/laravel-ide-helper · error · RuntimeException

Your IDE helper model hook must implement Barryvdh\LaravelId

Error message

Your IDE helper model hook must implement Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface

What it means

ide-helper:models iterates the classes listed in the `ide-helper.model_hooks` config array, resolves each through the container, and requires the instance to implement Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface (src/Console/ModelsCommand.php:1954-1969). This RuntimeException means one of the configured hooks is not a valid hook: it lacks the interface, is the wrong class entirely, or resolves to something unexpected through a container binding. Generation of model docs aborts at the offending hook.

Source

Thrown at src/Console/ModelsCommand.php:1962

        }

        return $parameterName;
    }

    /**
     * @param Model $model
     * @throws \Illuminate\Contracts\Container\BindingResolutionException
     * @throws \RuntimeException
     */
    protected function runModelHooks($model): void
    {
        $hooks = $this->laravel['config']->get('ide-helper.model_hooks', []);

        foreach ($hooks as $hook) {
            $hookInstance = $this->laravel->make($hook);

            if (!$hookInstance instanceof ModelHookInterface) {
                throw new \RuntimeException(
                    'Your IDE helper model hook must implement Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface'
                );
            }

            $hookInstance->run($this, $model);
        }
    }

    /**
     * @param Builder $schema
     * @param string $table
     */
    protected function setForeignKeys($schema, $table)
    {
        foreach ($schema->getForeignKeys($table) as $foreignKeyConstraint) {
            foreach ($foreignKeyConstraint['columns'] as $columnName) {
                $this->foreignKeyConstraintsColumns[] = $columnName;
            }

View on GitHub (pinned to 3a886dca5c)

Solutions

  1. Add `implements ModelHookInterface` (with the `use Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface;` import) to the class named in the error, and make sure it has `public function run(ModelsCommand $command, Model $model): void`.
  2. Verify the exact string in `ide-helper.model_hooks` matches the hook's fully qualified class name (no leading backslash needed in Laravel config, correct namespace).
  3. If the hook was written for an older ide-helper release, update it to the current ModelHookInterface contract and method signature.
  4. Run `composer dump-autoload` after creating or moving the hook class so the container can resolve it.
  5. Remove the entry from model_hooks if you no longer use that hook.

Example fix

// before: config/ide-helper.php
'model_hooks' => [\App\IdeHelper\AddUuidProperty::class],

// app/IdeHelper/AddUuidProperty.php
namespace App\IdeHelper;

class AddUuidProperty
{
    public function run($command, $model)
    {
        $command->setProperty($model, 'uuid', 'string', true, false, 'The uuid');
    }
}

// after
namespace App\IdeHelper;

use Barryvdh\LaravelIdeHelper\Console\ModelsCommand;
use Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface;
use Illuminate\Database\Eloquent\Model;

class AddUuidProperty implements ModelHookInterface
{
    public function run(ModelsCommand $command, Model $model): void
    {
        $command->setProperty($model, 'uuid', 'string', true, false, 'The uuid');
    }
}
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate config before running ide-helper:models
use Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface;

$bad = [];
foreach (config('ide-helper.model_hooks', []) as $hook) {
    if (!class_exists($hook) || !is_subclass_of($hook, ModelHookInterface::class)) {
        $bad[] = $hook;
    }
}
if ($bad) {
    fwrite(STDERR, 'Invalid model hooks: ' . implode(', ', $bad) . "\n");
    exit(1);
}

Type guard

use Barryvdh\LaravelIdeHelper\Contracts\ModelHookInterface;

function isModelHook(string $class): bool
{
    return class_exists($class) && is_subclass_of($class, ModelHookInterface::class);
}

Prevention

When it happens

Trigger: Running `php artisan ide-helper:models` with `ide-helper.model_hooks` containing a class that does not implement ModelHookInterface; a hook written against an older ide-helper version whose interface/contract path changed; a typo or wrong namespace in the config entry so the container resolves a different class; a container binding that overrides the configured class name.

Common situations: A custom hook copied from a blog post or another project that omits `implements ModelHookInterface`; upgrading laravel-ide-helper across a major version where the contract namespace moved; keeping the hook class behind a conditional binding that returns a decorator without the interface; typos in the config array after renaming the hook class.

Related errors


AI-assisted analysis of barryvdh/laravel-ide-helper@3a886dca5c (2026-08-23). Data as JSON: /api/errors/0af727061ad28aad. Report an issue: GitHub.