Bug Description
When creating a new location with coordinates, AdventureLog starts the background geocoding process twice for the same location.
Both geocoding attempts then fail with:
Location matching query does not exist.
The Location itself remains correctly stored in PostgreSQL and its coordinates are correct, but the geocoding process does not populate the associated city, country, or region.
Steps to Reproduce
- Create a new Location.
- Search for a place using the location search.
- Select a result with coordinates.
- Save the Location.
- Check the AdventureLog-SERVER container logs.
I reproduced this with a fresh AdventureLog database using the following location:
Hospital Vall d'Hebron
Barcelona, Barcelona, ES
Coordinates:
Latitude: 41.427041
Longitude: 2.140122
Expected Behavior
The location should trigger one background geocoding operation after it has been successfully created.
The geocoding process should complete successfully and populate the corresponding city, country, and region.
What actually happened?
The same location is geocoded twice almost simultaneously.
The backend logs show:
2026-08-25T13:11:27.854034940Z [AdventureLog-SERVER] [Location Geocode Thread] Starting geocode for location e41e77f2-984c-47a1-8317-1fdc948caa2d
2026-08-25T13:11:27.865796133Z [AdventureLog-SERVER] [Location Geocode Thread] Starting geocode for location e41e77f2-984c-47a1-8317-1fdc948caa2d
2026-08-25T13:11:27.893654171Z [AdventureLog-SERVER] [Location Geocode Thread] Error processing e41e77f2-984c-47a1-8317-1fdc948caa2d: Location matching query does not exist.
2026-08-25T13:11:27.912850613Z [AdventureLog-SERVER] [Location Geocode Thread] Error processing e41e77f2-984c-47a1-8317-1fdc948caa2d: Location matching query does not exist.
The two geocoding threads start only about 11 ms apart.
The Location remains present in PostgreSQL after the errors, with the correct coordinates, but city_id, country_id and region_id remain NULL.
Relevant database result
I verified the Location directly in PostgreSQL after the errors:
id | e41e77f2-984c-47a1-8317-1fdc948caa2d
name | Hospital Vall d'Hebron
location | Barcelona, Barcelona, ES
created_at | 2026-08-25 13:11:27.812434+00
updated_at | 2026-08-25 13:11:27.858858+00
city_id | NULL
country_id | NULL
region_id | NULL
The Location therefore still exists in the database after the geocoding errors.
Screenshots / Logs
2026-08-25T13:11:27.854034940Z [AdventureLog-SERVER] [Location Geocode Thread] Starting geocode for location e41e77f2-984c-47a1-8317-1fdc948caa2d
2026-08-25T13:11:27.865796133Z [AdventureLog-SERVER] [Location Geocode Thread] Starting geocode for location e41e77f2-984c-47a1-8317-1fdc948caa2d
2026-08-25T13:11:27.893654171Z [AdventureLog-SERVER] [Location Geocode Thread] Error processing e41e77f2-984c-47a1-8317-1fdc948caa2d: Location matching query does not exist.
2026-08-25T13:11:27.912850613Z [AdventureLog-SERVER] [Location Geocode Thread] Error processing e41e77f2-984c-47a1-8317-1fdc948caa2d: Location matching query does not exist.
Platform
Docker
Install Method
Docker Compose
AdventureLog Version
v0.13.0
Reverse Proxy
Synology reverse proxy
Docker Compose / Relevant Variables (Optional)
AdventureLog: v0.13.0
Deployment: Docker / Docker Compose
Host: Synology NAS
Architecture: x86_64
RAM: 16 GB
PostgreSQL: 16.15
PostGIS: 3.5.2
Gunicorn workers: 2
Django TIME_ZONE: UTC
Django USE_TZ: True
The database was freshly created, so there is no legacy data involved.
Additional Context
I inspected the source code inside the running v0.13.0 container.
The Location model starts background geocoding from its save() method whenever coordinates are present:
if has_coordinates(self.coordinates):
thread = threading.Thread(
target=background_geocode_and_assign,
args=(str(self.id),)
)
thread.daemon = True
thread.start()
The background function immediately retrieves the Location with:
location = Location.objects.get(id=location_id)
The Location serializer also appears to save the same Location twice during creation:
location = Location.objects.create(**validated_data)
...
location.save()
Since Location.objects.create() already calls save(), and save() starts the geocoding thread when coordinates are present, this appears to result in two background geocoding operations for the same Location.
The observed logs are consistent with this behavior.
There may also be a transaction/visibility race because the background thread attempts to retrieve the Location immediately after save(), potentially using a separate database connection.
I have not modified the application code or database. This behavior was reproduced using the unmodified v0.13.0 Docker image.
Relevant code / suspected cause
The relevant code appears to be in:
/code/adventures/models.py
/code/adventures/serializers.py
The serializer creates the Location and then explicitly calls save() again:
location = Location.objects.create(**validated_data)
...
location.save()
Meanwhile, Location.save() starts a background geocoding thread whenever coordinates are present.
This appears to cause duplicate geocoding.
A possible improvement might be to ensure that geocoding is scheduled only once, and possibly only after the database transaction has committed (for example using transaction.on_commit()).
This is only a suspected cause; I have not tested a code modification yet.
Confirmation
Bug Description
When creating a new location with coordinates, AdventureLog starts the background geocoding process twice for the same location.
Both geocoding attempts then fail with:
Location matching query does not exist.
The Location itself remains correctly stored in PostgreSQL and its coordinates are correct, but the geocoding process does not populate the associated city, country, or region.
Steps to Reproduce
I reproduced this with a fresh AdventureLog database using the following location:
Hospital Vall d'Hebron
Barcelona, Barcelona, ES
Coordinates:
Latitude: 41.427041
Longitude: 2.140122
Expected Behavior
The location should trigger one background geocoding operation after it has been successfully created.
The geocoding process should complete successfully and populate the corresponding city, country, and region.
What actually happened?
The same location is geocoded twice almost simultaneously.
The backend logs show:
2026-08-25T13:11:27.854034940Z [AdventureLog-SERVER] [Location Geocode Thread] Starting geocode for location e41e77f2-984c-47a1-8317-1fdc948caa2d
2026-08-25T13:11:27.865796133Z [AdventureLog-SERVER] [Location Geocode Thread] Starting geocode for location e41e77f2-984c-47a1-8317-1fdc948caa2d
2026-08-25T13:11:27.893654171Z [AdventureLog-SERVER] [Location Geocode Thread] Error processing e41e77f2-984c-47a1-8317-1fdc948caa2d: Location matching query does not exist.
2026-08-25T13:11:27.912850613Z [AdventureLog-SERVER] [Location Geocode Thread] Error processing e41e77f2-984c-47a1-8317-1fdc948caa2d: Location matching query does not exist.
The two geocoding threads start only about 11 ms apart.
The Location remains present in PostgreSQL after the errors, with the correct coordinates, but city_id, country_id and region_id remain NULL.
Relevant database result
I verified the Location directly in PostgreSQL after the errors:
id | e41e77f2-984c-47a1-8317-1fdc948caa2d
name | Hospital Vall d'Hebron
location | Barcelona, Barcelona, ES
created_at | 2026-08-25 13:11:27.812434+00
updated_at | 2026-08-25 13:11:27.858858+00
city_id | NULL
country_id | NULL
region_id | NULL
The Location therefore still exists in the database after the geocoding errors.
Screenshots / Logs
2026-08-25T13:11:27.854034940Z [AdventureLog-SERVER] [Location Geocode Thread] Starting geocode for location e41e77f2-984c-47a1-8317-1fdc948caa2d
2026-08-25T13:11:27.865796133Z [AdventureLog-SERVER] [Location Geocode Thread] Starting geocode for location e41e77f2-984c-47a1-8317-1fdc948caa2d
2026-08-25T13:11:27.893654171Z [AdventureLog-SERVER] [Location Geocode Thread] Error processing e41e77f2-984c-47a1-8317-1fdc948caa2d: Location matching query does not exist.
2026-08-25T13:11:27.912850613Z [AdventureLog-SERVER] [Location Geocode Thread] Error processing e41e77f2-984c-47a1-8317-1fdc948caa2d: Location matching query does not exist.
Platform
Docker
Install Method
Docker Compose
AdventureLog Version
v0.13.0
Reverse Proxy
Synology reverse proxy
Docker Compose / Relevant Variables (Optional)
Additional Context
I inspected the source code inside the running v0.13.0 container.
The Location model starts background geocoding from its save() method whenever coordinates are present:
if has_coordinates(self.coordinates):
thread = threading.Thread(
target=background_geocode_and_assign,
args=(str(self.id),)
)
thread.daemon = True
thread.start()
The background function immediately retrieves the Location with:
location = Location.objects.get(id=location_id)
The Location serializer also appears to save the same Location twice during creation:
location = Location.objects.create(**validated_data)
...
location.save()
Since Location.objects.create() already calls save(), and save() starts the geocoding thread when coordinates are present, this appears to result in two background geocoding operations for the same Location.
The observed logs are consistent with this behavior.
There may also be a transaction/visibility race because the background thread attempts to retrieve the Location immediately after save(), potentially using a separate database connection.
I have not modified the application code or database. This behavior was reproduced using the unmodified v0.13.0 Docker image.
Relevant code / suspected cause
The relevant code appears to be in:
/code/adventures/models.py
/code/adventures/serializers.py
The serializer creates the Location and then explicitly calls save() again:
location = Location.objects.create(**validated_data)
...
location.save()
Meanwhile, Location.save() starts a background geocoding thread whenever coordinates are present.
This appears to cause duplicate geocoding.
A possible improvement might be to ensure that geocoding is scheduled only once, and possibly only after the database transaction has committed (for example using transaction.on_commit()).
This is only a suspected cause; I have not tested a code modification yet.
Confirmation