phacility/phabricator · error · Exception
Option ("%s") is not a valid poll option. You may only vote
Error message
Option ("%s") is not a valid poll option. You may only vote for valid options. What it means
Thrown by PhabricatorSlowvoteVoteController when processing a ballot: each submitted option ID is checked against the poll's current option rows (the $options map). A vote value that is not a key in that set is rejected before any transaction or read lock is taken. It is server-side validation that the submitted ballot matches the poll as it currently exists in the database.
Source
Thrown at src/applications/slowvote/controller/PhabricatorSlowvoteVoteController.php:60
$message = pht('You must vote for something.');
} else {
$message = pht('You must vote for at least one option.');
}
return $this->newDialog()
->setTitle(pht('Stand For Something'))
->appendParagraph($message)
->addCancelButton($poll->getURI());
}
if ($is_plurality && count($votes) > 1) {
throw new Exception(
pht('In this poll, you may only vote for one option.'));
}
foreach ($votes as $vote) {
if (!isset($options[$vote])) {
throw new Exception(
pht(
'Option ("%s") is not a valid poll option. You may only '.
'vote for valid options.',
$vote));
}
}
$poll->openTransaction();
$poll->beginReadLocking();
$poll->reload();
$old_votes = id(new PhabricatorSlowvoteChoice())->loadAllWhere(
'pollID = %d AND authorPHID = %s',
$poll->getID(),
$viewer->getPHID());
$old_votes = mpull($old_votes, null, 'getOptionID');
View on GitHub (pinned to 5720a38cfe)
Solutions
- Reload the poll page and vote again so the form carries the current option IDs
- If automating, resolve the poll's current option IDs at runtime via PhabricatorSlowvoteOptionQuery with withPollIDs() instead of hardcoding them
- Filter submitted vote IDs against the poll's live options before sending the request
Example fix
// before: voting with a hardcoded option id $votes = array(999); // after: resolve the poll's current option ids first $options = id(new PhabricatorSlowvoteOptionQuery()) ->setViewer($viewer) ->withPollIDs(array($poll->getID())) ->execute(); $valid = array_fuse(mpull($options, 'getID')); $votes = array_intersect($votes, $valid);
Defensive patterns
Strategy: validation
Validate before calling
// Before voting, confirm every submitted option id exists on the poll.
$options = id(new PhabricatorSlowvoteOptionQuery())
->setViewer($viewer)
->withPollIDs(array($poll->getID()))
->execute();
$valid = array_fuse(mpull($options, 'getID'));
$votes = array_values(array_intersect($votes, array_keys($valid)));
if (!$votes) {
// every submitted option is stale; re-render the poll instead of posting
} Try / catch
Catch the plain Exception in the controller/HTTP layer and re-render the poll with a 'poll has changed, reload' dialog (the controller already builds AphrontDialogResponse for sibling failures like plurality violations); never retry the identical payload.
Prevention
- Submit votes only from a freshly rendered poll form
- Resolve option IDs from the poll at runtime instead of caching them
- Treat this exception as a permanent condition for the submitted ballot; fix the input, do not retry
When it happens
Trigger: POSTing a vote to the Slowvote controller with votes[] containing an option ID that has no PhabricatorSlowvoteOption row for that poll: a stale form rendered before the poll's options changed, a forged or hand-crafted HTTP request, or a race between page render and submit.
Common situations: Two browser tabs open on the same poll, one stale after options were edited; automation voting with hardcoded option IDs after the poll was recreated; a browser resubmitting a cached form.
Related errors
- You must select at least one project tag to add.
- Owner rule value is required. Specify a user to assign tasks
- Owner rule value must have only one elmement (value is "%s")
- You must select at least one project tag to remove.
- Too many relationships (%s, of type "%s").
AI-assisted analysis of phacility/phabricator@5720a38cfe (2026-08-21).
Data as JSON: /api/errors/487dd2141be74bdf.
Report an issue: GitHub.