{"record":{"id":"0af727061ad28aad","repo":"barryvdh/laravel-ide-helper","slug":"your-ide-helper-model-hook-must-implement-barryvdh","errorCode":null,"errorMessage":"Your IDE helper model hook must implement Barryvdh\\LaravelIdeHelper\\Contracts\\ModelHookInterface","messagePattern":"Your IDE helper model hook must implement Barryvdh\\\\LaravelIdeHelper\\\\Contracts\\\\ModelHookInterface","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Console/ModelsCommand.php","lineNumber":1962,"sourceCode":"        }\n\n        return $parameterName;\n    }\n\n    /**\n     * @param Model $model\n     * @throws \\Illuminate\\Contracts\\Container\\BindingResolutionException\n     * @throws \\RuntimeException\n     */\n    protected function runModelHooks($model): void\n    {\n        $hooks = $this->laravel['config']->get('ide-helper.model_hooks', []);\n\n        foreach ($hooks as $hook) {\n            $hookInstance = $this->laravel->make($hook);\n\n            if (!$hookInstance instanceof ModelHookInterface) {\n                throw new \\RuntimeException(\n                    'Your IDE helper model hook must implement Barryvdh\\LaravelIdeHelper\\Contracts\\ModelHookInterface'\n                );\n            }\n\n            $hookInstance->run($this, $model);\n        }\n    }\n\n    /**\n     * @param Builder $schema\n     * @param string $table\n     */\n    protected function setForeignKeys($schema, $table)\n    {\n        foreach ($schema->getForeignKeys($table) as $foreignKeyConstraint) {\n            foreach ($foreignKeyConstraint['columns'] as $columnName) {\n                $this->foreignKeyConstraintsColumns[] = $columnName;\n            }","sourceCodeStart":1944,"sourceCodeEnd":1980,"githubUrl":"https://github.com/barryvdh/laravel-ide-helper/blob/3a886dca5c7ec4854b316b1ac3bcdf9c43c1760b/src/Console/ModelsCommand.php#L1944-L1980","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: config/ide-helper.php\n'model_hooks' => [\\App\\IdeHelper\\AddUuidProperty::class],\n\n// app/IdeHelper/AddUuidProperty.php\nnamespace App\\IdeHelper;\n\nclass AddUuidProperty\n{\n    public function run($command, $model)\n    {\n        $command->setProperty($model, 'uuid', 'string', true, false, 'The uuid');\n    }\n}\n\n// after\nnamespace App\\IdeHelper;\n\nuse Barryvdh\\LaravelIdeHelper\\Console\\ModelsCommand;\nuse Barryvdh\\LaravelIdeHelper\\Contracts\\ModelHookInterface;\nuse Illuminate\\Database\\Eloquent\\Model;\n\nclass AddUuidProperty implements ModelHookInterface\n{\n    public function run(ModelsCommand $command, Model $model): void\n    {\n        $command->setProperty($model, 'uuid', 'string', true, false, 'The uuid');\n    }\n}","handlingStrategy":"type-guard","validationCode":"// Validate config before running ide-helper:models\nuse Barryvdh\\LaravelIdeHelper\\Contracts\\ModelHookInterface;\n\n$bad = [];\nforeach (config('ide-helper.model_hooks', []) as $hook) {\n    if (!class_exists($hook) || !is_subclass_of($hook, ModelHookInterface::class)) {\n        $bad[] = $hook;\n    }\n}\nif ($bad) {\n    fwrite(STDERR, 'Invalid model hooks: ' . implode(', ', $bad) . \"\\n\");\n    exit(1);\n}","typeGuard":"use Barryvdh\\LaravelIdeHelper\\Contracts\\ModelHookInterface;\n\nfunction isModelHook(string $class): bool\n{\n    return class_exists($class) && is_subclass_of($class, ModelHookInterface::class);\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["php","laravel","ide-helper","config","interface","model-hooks"],"backgroundTag":"interface-not-implemented","analyzedSha":"3a886dca5c7ec4854b316b1ac3bcdf9c43c1760b","analyzedAt":"2026-08-23T00:48:42.471Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}