{"record":{"id":"4c7e610793f073e9","repo":"yiisoft/yii2","slug":"controller-class-must-extend-from-yii-base-contro","errorCode":null,"errorMessage":"Controller class must extend from \\yii\\base\\Controller.","messagePattern":"Controller class must extend from \\\\yii\\\\base\\\\Controller\\.","errorType":"exception","errorClass":"InvalidConfigException","httpStatus":null,"severity":"error","filePath":"framework/base/Module.php","lineNumber":682,"sourceCode":"        }\n\n        if ($this->isIncorrectClassNameOrPrefix($className, $prefix)) {\n            return null;\n        }\n\n        $className = preg_replace_callback('%-([a-z0-9_])%i', function ($matches) {\n                return ucfirst($matches[1]);\n        }, ucfirst($className)) . 'Controller';\n        $className = ltrim($this->controllerNamespace . '\\\\' . str_replace('/', '\\\\', $prefix) . $className, '\\\\');\n        if (strpos($className, '-') !== false || !class_exists($className)) {\n            return null;\n        }\n\n        if (is_subclass_of($className, 'yii\\base\\Controller')) {\n            $controller = Yii::createObject($className, [$id, $this]);\n            return get_class($controller) === $className ? $controller : null;\n        } elseif (YII_DEBUG) {\n            throw new InvalidConfigException('Controller class must extend from \\\\yii\\\\base\\\\Controller.');\n        }\n\n        return null;\n    }\n\n    /**\n     * Checks if class name or prefix is incorrect\n     *\n     * @param string $className\n     * @param string $prefix\n     * @return bool\n     */\n    private function isIncorrectClassNameOrPrefix($className, $prefix)\n    {\n        if (!preg_match('%^[a-z][a-z0-9\\\\-_]*$%', $className)) {\n            return true;\n        }\n        if ($prefix !== '' && !preg_match('%^[a-z0-9_/]+$%i', $prefix)) {","sourceCodeStart":664,"sourceCodeEnd":700,"githubUrl":"https://github.com/yiisoft/yii2/blob/66f00d18a29b520f85e8e8f1e32d1e7e7b556cac/framework/base/Module.php#L664-L700","documentation":"In yii\\base\\Module::createControllerByID(), a controller class name was successfully derived (controllerNamespace + prefix + CamelCase ID + 'Controller'), contains no dash, and class_exists() is true — but is_subclass_of($className, 'yii\\base\\Controller') is false. Under YII_DEBUG this throws InvalidConfigException immediately; with debug off the method returns null and the failure surfaces later as the generic 'Unable to resolve the request' InvalidRouteException.","triggerScenarios":"A class with the derived name exists in the controller namespace but does not extend the framework base — e.g. a helper/model named FooController, or a scaffolded controller extending the wrong parent (copy-paste left \\yii\\db\\ActiveRecord or another class in extends); an IDE auto-import resolving 'Controller' to a non-controller class; composer classmap/alias loading a same-named class from a different directory.","commonSituations":"Code generation tools emitting plain classes; copy-paste of controller scaffolds followed by editing the extends clause; name collisions after adding vendor packages; a use statement importing a project-local Controller that is not itself a descendant of yii\\base\\Controller.","solutions":["Open the derived class named by the exception and change its parent to \\yii\\web\\Controller (web) or \\yii\\console\\Controller (console)","Rename or remove the colliding same-named class in that namespace / autoload mapping","Fix the use statement or composer classmap so autoloading resolves the intended controller file","Reproduce with YII_DEBUG enabled locally — production masks this as a plain route-resolution error"],"exampleFix":"// before\nnamespace app\\controllers;\n\nclass SiteController extends \\yii\\db\\ActiveRecord // wrong base class\n{\n}\n\n// after\nnamespace app\\controllers;\n\nclass SiteController extends \\yii\\web\\Controller\n{\n}","handlingStrategy":"type-guard","validationCode":"$className = 'app\\\\controllers\\\\' . str_replace(' ', '', ucwords(str_replace('-', ' ', $id))) . 'Controller';\nif (class_exists($className) && !is_subclass_of($className, \\yii\\base\\Controller::class)) {\n    throw new \\RuntimeException($className . ' does not extend yii\\\\base\\\\Controller');\n}","typeGuard":"function isControllerClass(string $class): bool\n{\n    return class_exists($class) && is_subclass_of($class, \\yii\\base\\Controller::class);\n}","tryCatchPattern":"try {\n    Yii::$app->runAction($route);\n} catch (\\yii\\base\\InvalidConfigException $e) {\n    // YII_DEBUG-only signal that a controller class has the wrong parent — fix code, do not catch in prod\n}","preventionTips":["Standardize controller scaffolds so extends always targets \\yii\\web\\Controller or \\yii\\console\\Controller","Run a CI check asserting every *Controller class under the controller path is a Controller subclass","Keep controller namespaces free of non-controller classes with Controller-suffixed names"],"tags":["php","yii2","controller","inheritance","debug-mode"],"backgroundTag":"invalid-controller-class","analyzedSha":"66f00d18a29b520f85e8e8f1e32d1e7e7b556cac","analyzedAt":"2026-08-17T05:17:23.470Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}