How to avoid 404 error on new extension installation

As @Cags said, this is not (easily) possible because the ACL tree is loaded when the session is initialized (AKA when the admin logs in).
A possible workaround would be to override the _isSectionAllowed method in system configuration controller: (Mage_Adminhtml_System_ConfigController::_isSectionAllowed) and make it reload the ACL tree.
Something like:

protected function _isSectionAllowed($section)
{
    $session = Mage::getSingleton('admin/session');
    $session->setAcl(Mage::getResourceModel('admin/acl')->loadAcl());//reload the tree
    return parent::_isSectionAllowed($secntion); //all the code from the original method
}

But this means the ACL tree will be reloaded every time you access a config section. I see no point in doing this.
Also you cannot do it for one specific extension. You will have to rewrite the core class.


I found a way around this with very little customization. What we need is:

  1. A new controller action that reloads the ACL (without logging out and in), then redirects back to the previous page:

    class SSE_AclReload_Adminhtml_Permissions_AclReloadController extends Mage_Adminhtml_Controller_Action
    {
        public function indexAction()
        {
            $session = Mage::getSingleton('admin/session');
            $session->setAcl(Mage::getResourceModel('admin/acl')->loadAcl());
            Mage::getSingleton('adminhtml/session')->addSuccess($this->__('ACL reloaded'));
            $this->_redirectReferer();
        }
    }
    
  2. A layout update for the admin_noroute handle. We will add a link to this new controller action directly on the admin 404 page:

    <layout version="0.1.0">
        <adminhtml_noroute>
            <reference name="content">
                <block type="adminhtml/template" name="content.aclReload" after="content.noRoute" template="sse_aclreload/button.phtml" />
            </reference>
        </adminhtml_noroute>
    </layout>
    
  3. And the template with the link:

    <a href="<?php echo $this->getUrl('adminhtml/permissions_aclReload/index'); ?>">
        <?php echo $this->__('Reload ACL'); ?>
    </a>
    

I threw it together into a small extension on Github: SSE_AclReload (adds the link also to the System > Permissions menu)

You could also try to reload the ACL automatically as soon as the admin/noroute action is dispatched, but I prefer to 1) know what's going on and 2) have a choice.