hook_menu not producing expected tab structure, problem? I'm trying to create a tabbed menu system with hook_menu() following the hook documentation and Clive's answer. I am using the following code.

/**
 * Implements hook_menu().
 */
function newforms_menu() {
  $items = array();
  $items['admin/config/content/newforms'] = array(
    'title' =&gt; 'NewForms',
    'description' =&gt; 'Configure web forms via drag and drop.',
    'page callback' =&gt; 'drupal_get_form',
    'page arguments' =&gt; array('newforms_administration_settings'),
    'access arguments' =&gt; array('administer newforms module'),
    'file' =&gt; 'newforms.admin.inc',
  );

  $items['admin/config/content/newforms/list'] = array(
    'title' =&gt; 'Forms',
    'type' =&gt; MENU_DEFAULT_LOCAL_TASK,
    'weight' =&gt; -10,
  );

  $items['admin/config/content/newforms/components'] = array(
    'title' =&gt; 'Components',
    'type' =&gt; MENU_LOCAL_TASK,
    'page arguments' =&gt; array('newforms_components_list'),
  );

  return $items;
}


I would expect this to produce two tabs, labeled 'Forms' and 'Components', but it does not. I see no tabs.  On admin/config/content/newforms/list, I get the same page as admin/config/content/newforms; on admin/config/content/newforms/components, I get "You are not authorized to access this page." 

I've cleared cache and ran cron, disabled the module, uninstalled it, reinstalled it, cleared cache, and ran cron; I get the same results.
Both callback argument form functions are defined in newforms.admin.inc. 

Do you have any idea as to what is going on here?
So this works:

/**
 * Implements hook_menu().
 */
function newforms_menu() {
  $items = array();
  $items['admin/config/content/newforms'] = array(
    'title' =&gt; 'NewForms',
    'description' =&gt; 'Configure web forms via drag and drop.',
    'page callback' =&gt; 'drupal_get_form',
    'page arguments' =&gt; array('newforms_administration_settings'),
    'access arguments' =&gt; array('administer newforms module'),
    'file' =&gt; 'newforms.admin.inc',
  );

  $items['admin/config/content/newforms/list'] = array(
    'title' =&gt; 'Forms',
    'type' =&gt; MENU_DEFAULT_LOCAL_TASK,
    'weight' =&gt; -10,
  );

  $items['admin/config/content/newforms/components'] = array(
    'title' =&gt; 'Components',
    'type' =&gt; MENU_LOCAL_TASK,
    'page arguments' =&gt; array('newforms_components_list'),
    'access arguments' =&gt; array('administer newforms module'),
  );

  return $items;
}


I think there were two things happening.  I have two theories.  One was that Drupal essentially saw two identical tabs and said "this is dumb I'm not doing this" and didn't render the components tab.  The other theory is that as soon as Drupal saw a different page argument for the second tab (components), it demanded an access arguments specification.  I'm not sure which is true, if both are true, or if both are wrong, but this works.

The moral of the story is that things in hook_menu don't inherit the way you expect them to sometimes.

EDIT:

This is straight from the hook_menu documentation.

// Make "Foo settings" appear on the admin Config page
$items['admin/config/system/foo'] = array(
  'title' =&gt; 'Foo settings',
  'type' =&gt; MENU_NORMAL_ITEM,
  // Page callback, etc. need to be added here.
);
// Make "Tab 1" the main tab on the "Foo settings" page
$items['admin/config/system/foo/tab1'] = array(
  'title' =&gt; 'Tab 1',
  'type' =&gt; MENU_DEFAULT_LOCAL_TASK,
  // Access callback, page callback, and theme callback will be inherited
  // from 'admin/config/system/foo', if not specified here to override.
);
// Make an additional tab called "Tab 2" on "Foo settings"
$items['admin/config/system/foo/tab2'] = array(
  'title' =&gt; 'Tab 2',
  'type' =&gt; MENU_LOCAL_TASK,
  // Page callback and theme callback will be inherited from
  // 'admin/config/system/foo', if not specified here to override.
  // Need to add access callback or access arguments.
);


The second to last line is what tripped me up.  For every MENU_LOCAL_TASK you must add an access callback/access argument.  Mystery solved.