phacility/phabricator · error · ConduitException

ERR_BAD_POLL

ERR_BAD_POLL

Error message

ERR_BAD_POLL

What it means

Conduit method slowvote.info loads the poll by ID via PhabricatorSlowvoteQuery under the acting viewer; when no poll loads (nonexistent ID, deleted poll, or a poll the authenticated user cannot see due to policies) it throws ConduitException('ERR_BAD_POLL'), which the Conduit pipeline surfaces to API clients as an error with that code.

Source

Thrown at src/applications/slowvote/conduit/SlowvoteInfoConduitAPIMethod.php:47

  }

  protected function defineErrorTypes() {
    return array(
      'ERR_BAD_POLL' => pht('No such poll exists.'),
    );
  }

  protected function execute(ConduitAPIRequest $request) {
    $viewer = $this->getViewer();

    $poll_id = $request->getValue('poll_id');

    $poll = id(new PhabricatorSlowvoteQuery())
      ->setViewer($viewer)
      ->withIDs(array($poll_id))
      ->executeOne();
    if (!$poll) {
      throw new ConduitException('ERR_BAD_POLL');
    }

    $result = array(
      'id'          => $poll->getID(),
      'phid'        => $poll->getPHID(),
      'authorPHID'  => $poll->getAuthorPHID(),
      'question'    => $poll->getQuestion(),
      'uri'         => PhabricatorEnv::getProductionURI('/V'.$poll->getID()),
    );

    return $result;
  }

}

View on GitHub (pinned to 5720a38cfe)

Solutions

  1. Verify the poll exists at /V<id> in the web UI while logged in as the same account the token belongs to
  2. Discover valid IDs first via slowvote.query under the same credentials
  3. Treat ERR_BAD_POLL as a skip-and-continue condition in iterators instead of aborting
  4. Confirm you passed poll_id (the numeric ID), not a PHID

Example fix

// before
$info = $conduit->executeMethod('slowvote.info', array('poll_id' => $id));

// after: confirm visibility first, then fetch
$polls = $conduit->executeMethod('slowvote.query', array('ids' => array($id)));
if (!$polls) {
  continue;
}
$info = $conduit->executeMethod('slowvote.info', array('poll_id' => $id));
Defensive patterns

Strategy: try-catch

Validate before calling

// Discover visible polls under the same credentials before fetching
$polls = $conduit->executeMethod(
  'slowvote.query',
  array('ids' => array($pollId)));
if (!$polls) {
  // skip: poll missing or invisible to this token
}

Try / catch

try {
  $info = $conduit->executeMethod('slowvote.info', array('poll_id' => $id));
} catch (ConduitException $ex) {
  if ($ex->getMessage() === 'ERR_BAD_POLL') {
    // nonexistent or not visible: skip and continue the iteration
  } else {
    throw $ex;
  }
}

Prevention

When it happens

Trigger: Conduit call slowvote.info with {"poll_id": N} where N does not exist, was deleted, or is policy-restricted relative to the Conduit token's user.

Common situations: Scripts iterating a range of poll IDs that include deleted ones; bot/API tokens whose accounts lack visibility on the poll; carrying IDs between dev and prod environments where they differ.

Related errors


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