-
Notifications
You must be signed in to change notification settings - Fork 1
Can't change vote multiple times on off-chain proposals #36
Description
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
- Create or find an off-chain proposal with XTZ-weighted voting
- Vote on a choice
- Change your vote to a different choice - this works
- Try to change your vote again
- 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.