dOrgTech / dOrgTech/homebase-lite-backend
Can't change vote multiple times on off-chain proposals
- Dominant language
- JavaScript
- Stars
- 2
- Forks
- 1
- PR merge metrics
- No merged PRs in 30d
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
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:
```javascript
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 #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:
```javascript
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.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.