phacility/phabricator · error · Exception

No such key '%s' to add menu item after!

Error message

No such key '%s' to add menu item after!

What it means

PHUIListView::addMenuItemAfter($key, $item) inserts $item directly after the existing item whose key equals $key (keys are set with PHUIListItemView::setKey()). Before inserting, the list resolves the anchor via getItem($key), which scans its items, and throws when no item carries that key — a typo, a name-vs-key mixup, or an anchor that is added later all fail.

Source

Thrown at src/view/phui/PHUIListView.php:68

      ->setHref($href);

    $this->addMenuItem($item);

    return $item;
  }

  public function addMenuItem(PHUIListItemView $item) {
    return $this->addMenuItemAfter(null, $item);
  }

  public function addMenuItemAfter($key, PHUIListItemView $item) {
    if ($key === null) {
      $this->items[] = $item;
      return $this;
    }

    if (!$this->getItem($key)) {
      throw new Exception(pht("No such key '%s' to add menu item after!",
        $key));
    }

    $result = array();
    foreach ($this->items as $other) {
      $result[] = $other;
      if ($other->getKey() == $key) {
        $result[] = $item;
      }
    }

    $this->items = $result;
    return $this;
  }

  public function addMenuItemBefore($key, PHUIListItemView $item) {
    if ($key === null) {
      array_unshift($this->items, $item);

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Verify the anchor exists with $list->getItem($key) and fix any typo or missing setKey() call.
  2. When the anchor is optional, branch: if getItem($key) is truthy use addMenuItemAfter(), otherwise addMenuItem() to append.
  3. Centralize menu keys as class constants so set and lookup sites cannot drift.

Example fix

// before
$list->addMenuItemAfter('revisions', $item); // no item keyed 'revisions'

// after
$anchor = id(new PHUIListItemView())
  ->setKey('revisions')
  ->setName(pht('Revisions'))
  ->setHref('/differential/');
$list->addMenuItem($anchor);
$list->addMenuItemAfter('revisions', $item);
Defensive patterns

Strategy: validation

Validate before calling

if ($list->getItem($key)) {
  $list->addMenuItemAfter($key, $item);
} else {
  $list->addMenuItem($item); // no anchor: append at the end
}

Prevention

When it happens

Trigger: addMenuItemAfter('home', $item) when no item was created with setKey('home'); referencing an item by display name instead of its key; adding the anchor item after the insert call.

Common situations: Dynamically built menus where anchor items are conditionally omitted; copy-paste from a menu with different keys; refactors that rename keys but not every reference.

Related errors


AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21). Data as JSON: /api/errors/ea72dfd201fb72b2. Report an issue: GitHub.