Skip to content

Bug: Concurrency Race Condition causes silent data loss in Raid XP #404

@basantnema31

Description

@basantnema31

Description

In src/app/api/raid/execute/route.ts, the defender and attacker's
aid_xp are updated using values computed in application memory based on reads that occurred at the very beginning of the request:

typescript await Promise.all([ admin.from("developers").update({ raid_xp: (attacker.raid_xp ?? 0) + XP_WIN_ATTACKER }).eq("id", attacker.id), admin.from("developers").update({ raid_xp: (defender.raid_xp ?? 0) + XP_WIN_DEFENDER }).eq("id", defender.id), ]);

Because the atomic execute_raid RPC executes in between the initial read and this update, any concurrent XP changes to the defender (e.g. they defended another raid concurrently, or completed a daily mission granting XP) will be completely overwritten by this stale update, resulting in silent data loss for users.

Recommendation

Update the
aid_xp natively inside the execute_raid RPC function in Supabase where row-level locks prevent concurrent data races, rather than doing it in the Node environment.

Metadata

Metadata

Assignees

Labels

Gssoc 26Part of GirlScript Summer of Code 2026backendBackend/API relatedgood first issueGood for newcomersgssoc:approvedApproved GSSoC contributionlevel:intermediateIntermediate difficulty leveltype:bugSomething isn't working as expected

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions