Skip to content

Race condition in admin suggestion processing allows incomplete state #312

@coderabbitai

Description

@coderabbitai

Description

A race condition exists in the admin suggestion processing endpoint that can leave suggestions in an inconsistent state when concurrent requests attempt to accept the same suggestion.

Technical Details

Location: goodmap/core_api.py in admin_update_suggestion() endpoint (lines ~494-522)

Problem: TOCTOU (Time-of-Check-Time-of-Use) gap between:

  1. database.get_suggestion() - checking if status is 'pending'
  2. database.add_location() - adding the location
  3. database.update_suggestion() - updating the status

Scenario:
When two concurrent requests accept the same suggestion:

  1. Both read the suggestion and see status='pending'
  2. Request A successfully adds the location and updates the suggestion status
  3. Request B's add_location call detects the duplicate and raises LocationAlreadyExistsError
  4. Request B returns 409 "Location already exists" without marking the suggestion as processed
  5. The suggestion remains in "pending" state despite being accepted

While duplicate location entries are prevented, the suggestion status becomes inconsistent, confusing admin users who receive a 409 error.

Proposed Solutions

Option 1: Database Transactions
Wrap add_location and update_suggestion in a database transaction/session (MongoDB supports sessions) so both operations succeed together or roll back together.

Option 2: Compare-and-Swap
Implement atomic verify-and-update in database.update_suggestion():

  • Accept an expected_status parameter (e.g., expected='pending')
  • Return whether the update succeeded
  • Only call database.add_location() if the CAS succeeded

Option 3: Graceful Duplicate Handling
When add_location raises LocationAlreadyExistsError, treat it as a successful accept and mark the suggestion as processed (or already-accepted).

Context

Files Affected

  • goodmap/core_api.py - admin_update_suggestion() endpoint
  • goodmap/db.py - suggestion and location database operations

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions