{"record":{"id":"6bf03ece95a3b90c","repo":"FreshRSS/FreshRSS","slug":"invalid-action-name-action-name-for-controller","errorCode":null,"errorMessage":"Invalid action name “{action_name}” for controller “{controller_name}”.","messagePattern":"Invalid action name “(.+?)” for controller “(.+?)”\\.","errorType":"http","errorClass":"Minz_ActionException","httpStatus":404,"severity":"error","filePath":"lib/Minz/Dispatcher.php","lineNumber":115,"sourceCode":"\t\tif (!($controller instanceof Minz_ActionController)) {\n\t\t\tthrow new Minz_ControllerNotActionControllerException(\n\t\t\t\t$controller_name,\n\t\t\t\tMinz_Exception::ERROR\n\t\t\t);\n\t\t}\n\n\t\t$this->controller = $controller;\n\t}\n\n\t/**\n\t * Launch the action on the dispatcher’s controller\n\t * @param string $action_name the name of the action\n\t * @throws Minz_ActionException if the action cannot be executed on the controller\n\t */\n\tprivate function launchAction(string $action_name): void {\n\t\t$call = [$this->controller, $action_name];\n\t\tif (!is_callable($call)) {\n\t\t\tthrow new Minz_ActionException(\n\t\t\t\tget_class($this->controller),\n\t\t\t\t$action_name,\n\t\t\t\tMinz_Exception::ERROR\n\t\t\t);\n\t\t}\n\t\tif (Minz_ExtensionManager::callHook(Minz_HookType::ActionExecute, $this->controller) !== false) {\n\t\t\tcall_user_func($call);\n\t\t}\n\t}\n\n\t/**\n\t * Register a controller file.\n\t *\n\t * @param string $base_name the base name of the controller (i.e. ./?c=<base_name>)\n\t * @param string $base_path the base path where we should look into to find info.\n\t */\n\tpublic static function registerController(string $base_name, string $base_path): void {\n\t\tif (!self::isRegistered($base_name)) {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/FreshRSS/FreshRSS/blob/95842d81c1b8ab673389544f072559aeb8cd7591/lib/Minz/Dispatcher.php#L97-L133","documentation":"Minz_Dispatcher::launchAction() builds the callable [$this->controller, $action_name] and requires is_callable(); in practice the controller must expose a public instance method <action>Action(). Otherwise Minz_ActionException is thrown, carrying the controller class name and the raw action name from the URL.","triggerScenarios":"?c=<controller>&a=<action> where method <action>Action() does not exist or is not public (private/protected, or static); an action renamed in a FreshRSS upgrade while old links or clients still request the previous name; an extension route pointing at a method that was never implemented.","commonSituations":"Bookmarked URLs after an upgrade renamed actions; third-party mobile clients calling removed endpoints; typos in hand-written URLs; extension development against a changed controller.","solutions":["Check the 'a' value and confirm a public method <action>Action() exists on the controller class named in the message","If FreshRSS renamed the action, update the URL, bookmark, or client to the new name","For custom actions, implement public function <action>Action(): void on the controller","When generating links dynamically, build them from the controller's actual action names"],"exampleFix":"// before: link still uses the old action name after a rename\necho Minz_Url::display(['c' => 'feed', 'a' => 'oldName']);\n\n// after: rename kept consistent with the controller method\n// controller: public function newNameAction(): void { ... }\necho Minz_Url::display(['c' => 'feed', 'a' => 'newName']);","handlingStrategy":"validation","validationCode":"$action = 'update';\n$method = $action . 'Action';\nif (!is_callable([$controller, $method])) {\n\t// the URL requests an action this controller does not expose: use the default action\n\t$action = 'index';\n}","typeGuard":"function actionIsCallable(object $controller, string $action): bool {\n\treturn is_callable([$controller, $action . 'Action']);\n}","tryCatchPattern":"try {\n\t// dispatch the request\n} catch (Minz_ActionException $e) {\n\t// controller/action pair from the URL does not exist: render 404\n\tMinz_Error::error(404, ['error_message' => 'Unknown action ' . $e->getMessage()]);\n}","preventionTips":["Verify is_callable([$controller, $action . 'Action']) before building action URLs dynamically","Keep action names in sync when renaming: update links, clients, and bookmarks in the same change","Implement actions as public instance methods; private/static ones are not dispatchable","Catch Minz_ActionException at the front controller and degrade to 404"],"tags":["minz","dispatcher","routing","action","reflection"],"backgroundTag":"action-not-found","analyzedSha":"95842d81c1b8ab673389544f072559aeb8cd7591","analyzedAt":"2026-08-23T00:21:00.265Z","schemaVersion":2},"datasetVersion":"2026-08-23T01:17:44.959Z"}