phacility/phabricator · error · Exception

You must pass the user to %s.

Error message

You must pass the user to %s.

What it means

AphrontFormView::render() requires the acting user because phabricator_form() embeds viewer-dependent session/CSRF metadata into the form markup. render() calls hasViewer(), inherited from AphrontView, and throws when no viewer was ever set with setUser()/setViewer(). The check fires at render time, typically deep inside a page, dialog, or controller response.

Source

Thrown at src/view/form/AphrontFormView.php:138

   * controls. It will propagate some information from the form to the
   * control to simplify rendering.
   *
   * @param AphrontFormControl Control to append.
   * @return this
   */
  public function appendControl(AphrontFormControl $control) {
    $this->controls[] = $control;
    return $this->appendChild($control);
  }


  public function render() {
    require_celerity_resource('phui-form-view-css');

    $layout = $this->buildLayoutView();

    if (!$this->hasViewer()) {
      throw new Exception(
        pht(
          'You must pass the user to %s.',
          __CLASS__));
    }

    $sigils = $this->sigils;
    if ($this->workflow) {
      $sigils[] = 'workflow';
    }

    return phabricator_form(
      $this->getViewer(),
      array(
        'class'   => implode(' ', $this->classes),
        'action'  => $this->action,
        'method'  => $this->method,
        'enctype' => $this->encType,
        'sigil'   => $sigils ? implode(' ', $sigils) : null,

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Call $form->setUser($viewer) (or setViewer($viewer)) immediately after constructing the form.
  2. In controllers, always pass $this->getViewer().
  3. For non-request contexts, load and pass an explicit acting PhabricatorUser before rendering.

Example fix

// before
$form = id(new AphrontFormView())
  ->appendChild($control);
// no user set; render() throws

// after
$form = id(new AphrontFormView())
  ->setUser($viewer)
  ->appendControl($control);
Defensive patterns

Strategy: validation

Validate before calling

if (!$form->hasViewer()) {
  $form->setUser($viewer);
}
$html = $form->render();

Prevention

When it happens

Trigger: Building an AphrontFormView in a controller, dialog, or standalone script and rendering it without ever calling $form->setUser($viewer) (or setViewer($viewer)).

Common situations: A new custom form where the setUser() line was forgotten; rendering forms from CLI scripts, daemons, or mail generation where no viewer exists; refactors that restructure form builders and drop the user assignment.

Related errors


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