{"record":{"id":"da522eb517a81902","repo":"phacility/phabricator","slug":"you-must-pass-the-user-to-s","errorCode":null,"errorMessage":"You must pass the user to %s.","messagePattern":"You must pass the user to (.+?)\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"src/view/form/AphrontFormView.php","lineNumber":138,"sourceCode":"   * controls. It will propagate some information from the form to the\n   * control to simplify rendering.\n   *\n   * @param AphrontFormControl Control to append.\n   * @return this\n   */\n  public function appendControl(AphrontFormControl $control) {\n    $this->controls[] = $control;\n    return $this->appendChild($control);\n  }\n\n\n  public function render() {\n    require_celerity_resource('phui-form-view-css');\n\n    $layout = $this->buildLayoutView();\n\n    if (!$this->hasViewer()) {\n      throw new Exception(\n        pht(\n          'You must pass the user to %s.',\n          __CLASS__));\n    }\n\n    $sigils = $this->sigils;\n    if ($this->workflow) {\n      $sigils[] = 'workflow';\n    }\n\n    return phabricator_form(\n      $this->getViewer(),\n      array(\n        'class'   => implode(' ', $this->classes),\n        'action'  => $this->action,\n        'method'  => $this->method,\n        'enctype' => $this->encType,\n        'sigil'   => $sigils ? implode(' ', $sigils) : null,","sourceCodeStart":120,"sourceCodeEnd":156,"githubUrl":"https://github.com/phacility/phabricator/blob/5720a38cfe95b00ca4be5016dd0d2f3195f4fa04/src/view/form/AphrontFormView.php#L120-L156","documentation":"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.","triggerScenarios":"Building an AphrontFormView in a controller, dialog, or standalone script and rendering it without ever calling $form->setUser($viewer) (or setViewer($viewer)).","commonSituations":"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.","solutions":["Call $form->setUser($viewer) (or setViewer($viewer)) immediately after constructing the form.","In controllers, always pass $this->getViewer().","For non-request contexts, load and pass an explicit acting PhabricatorUser before rendering."],"exampleFix":"// before\n$form = id(new AphrontFormView())\n  ->appendChild($control);\n// no user set; render() throws\n\n// after\n$form = id(new AphrontFormView())\n  ->setUser($viewer)\n  ->appendControl($control);","handlingStrategy":"validation","validationCode":"if (!$form->hasViewer()) {\n  $form->setUser($viewer);\n}\n$html = $form->render();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Make setUser($viewer) the first fluent call on every AphrontFormView.","hasViewer() is public on every AphrontView — assert it in shared render pipelines.","In controllers, always source the viewer from $this->getViewer()."],"tags":["php","phabricator","form","viewer","csrf"],"backgroundTag":"missing-viewer-context","analyzedSha":"5720a38cfe95b00ca4be5016dd0d2f3195f4fa04","analyzedAt":"2026-08-21T05:07:25.672Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}