phacility/phabricator · error · Exception

Attempting to update comment content state, but request has

Error message

Attempting to update comment content state, but request has no content state.

What it means

Thrown by updateCommentContentState() when it is asked to apply content state from a request whose `hasContentState` boolean flag is false/absent. Content state is the structured payload for comments with advanced storage (images, performed-actions, checklists): the client must declare `hasContentState=1` and send the state. Calling the update path without the declaration is a client/protocol mismatch, so the controller refuses rather than silently wiping the comment's state.

Source

Thrown at src/infrastructure/diff/PhabricatorInlineCommentController.php:567

      $inline = $inline->newInlineCommentObject();
    }

    return $inline;
  }

  private function hasContentState() {
    $request = $this->getRequest();
    return (bool)$request->getBool('hasContentState');
  }

  private function newRequestContentState($inline) {
    $request = $this->getRequest();
    return $inline->newContentStateFromRequest($request);
  }

  private function updateCommentContentState(PhabricatorInlineComment $inline) {
    if (!$this->hasContentState()) {
      throw new Exception(
        pht(
          'Attempting to update comment content state, but request has no '.
          'content state.'));
    }

    $state = $this->newRequestContentState($inline);
    $inline->setContentState($state);
  }

  private function saveComment(PhabricatorInlineComment $inline) {
    $viewer = $this->getViewer();
    $draft_engine = $this->newDraftEngine();

    $inline->openTransaction();
      $inline->save();

      PhabricatorVersionedDraft::purgeDrafts(
        $inline->getPHID(),

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Send `hasContentState=1` together with the content state fields the client supports (the standard comment form does this)
  2. If the comment genuinely has no advanced state, use the plain comment-save path instead of the content-state path
  3. For custom clients, mirror the fields emitted by the upstream comment form (inspect a real submit in the network tab)
Defensive patterns

Strategy: validation

Validate before calling

// Client-side or in a custom controller: declare content state
// whenever the payload includes state fields
$has_state = ($images || $actions || $checklist);
if ($has_state) {
  $payload['hasContentState'] = 1;
  $payload += $state_fields;
}

Prevention

When it happens

Trigger: POSTing an inline comment save/preview where `hasContentState` is omitted or 0 but the code path (subclass of PhabricatorInlineCommentController, e.g. transaction-based comment editing) calls updateCommentContentState(); custom clients or old UI code that never sends the flag; hand-built forms replicating the comment endpoint.

Common situations: Custom frontends or test harnesses posting to the inline endpoints without the modern comment form fields; browser extensions injecting forms; partial upgrades where cached JS no longer matches the server protocol.

Related errors


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