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
- 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`.
- 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).
- If the hook was written for an older ide-helper release, update it to the current ModelHookInterface contract and method signature.
- Run `composer dump-autoload` after creating or moving the hook class so the container can resolve it.
- 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
- Write hooks against the shipped interface and add a static check (is_subclass_of) to your test suite for every entry in ide-helper.model_hooks.
- Re-check hook signatures after every major laravel-ide-helper upgrade.
- Reference hooks by ::class constants in config so renames surface as IDE errors, not runtime ones.
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
- Class '$class' not found.
- Cannot generate Eloquent helper
- Cannot load template for {name}: {message}
- Error resolving relation model of %s:%s() : %s
AI-assisted analysis of barryvdh/laravel-ide-helper@3a886dca5c (2026-08-23).
Data as JSON: /api/errors/0af727061ad28aad.
Report an issue: GitHub.