Skip to content

Can't change vote multiple times on off-chain proposals #36

@EightRice

Description

@EightRice

After voting once on an off-chain proposal, attempting to change the vote a second time results in an error. This happens in both production and the deploy preview, so it's not related to PR #35.

Steps to Reproduce

  1. Create or find an off-chain proposal with XTZ-weighted voting
  2. Vote on a choice
  3. Change your vote to a different choice - this works
  4. Try to change your vote again
  5. Error is thrown

[Screenshot: Error message in console]

Error Details

Error message:

Error: Cannot read properties of null (reading 'walletAddresses')

Backend logs:

[choices.update:tz:error] {
  reqId: 'mi2xgcrv-kiidwm',
  error: "Cannot read properties of null (reading 'walletAddresses')",
  stack: "TypeError: Cannot read properties of null (reading 'walletAddresses')\n" +
    '    at updateChoiceById (C:\\code\\homebase-lite-backend\\components\\choices\\index.js:265:45)\n' +
    '    at process.processTicksAndRejections (node:internal/process/task_queues:105:5)'
}

Root Cause

In components/choices/index.js around line 262-265:

if (isVoted.length > 0) {
  const oldVoteObj = isVoted[0].walletAddresses.find(x => x.address === address);
  oldVote = await ChoiceModel.findById(oldVoteObj.choiceId);

  const oldSignaturePayload = oldVote.walletAddresses[0].payloadBytes  // <-- oldVote is null!

The code tries to find the old vote's choice document, but findById returns null when the choice document doesn't exist. This happens when there's a database inconsistency where the vote reference exists but the actual choice document was deleted or is missing.

Impact

  • Users can only change their vote once
  • After the first change, they're stuck with that choice
  • This affects user experience on longer voting periods where opinions might change

Notes

  • This is a pre-existing bug, not introduced by PR feat:Include Staked Balance #35
  • The issue appears to be related to orphaned choice references in the database
  • Needs null check before accessing oldVote.walletAddresses

Suggested Fix

Add a null check:

if (isVoted.length > 0) {
  const oldVoteObj = isVoted[0].walletAddresses.find(x => x.address === address);
  oldVote = await ChoiceModel.findById(oldVoteObj.choiceId);

  if (!oldVote) {
    throw new Error('Previous vote choice not found - database inconsistency');
  }

  const oldSignaturePayload = oldVote.walletAddresses[0].payloadBytes
  // ... rest of the logic
}

Though this might just surface the underlying database inconsistency issue. May need to investigate why choice documents are getting deleted or not created properly.

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions